@taskforcehq/taskforce 0.3.306 → 0.3.308
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/README.md +0 -2
- package/dist/Taskforce.module.css +317 -27
- package/dist/TaskforceCore.js +1 -0
- package/dist/TaskforceCore.test.js +178 -0
- package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
- package/dist/components/activity/EntityActivityTimeline.js +81 -0
- package/dist/components/context/ContextAttachmentManager.js +15 -3
- package/dist/components/features/AgentsModule.d.ts +5 -1
- package/dist/components/features/AgentsModule.js +142 -39
- package/dist/components/features/AgentsModule.test.js +260 -11
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
- package/dist/components/features/DocumentIndex.d.ts +2 -2
- package/dist/components/features/DocumentIndex.js +3 -4
- package/dist/components/features/DocumentViewer.d.ts +3 -1
- package/dist/components/features/DocumentViewer.js +6 -5
- package/dist/components/features/DocumentWorkspace.d.ts +10 -2
- package/dist/components/features/DocumentWorkspace.js +15 -4
- package/dist/components/features/DocumentWorkspace.test.js +20 -3
- package/dist/components/features/TaskSettings.d.ts +2 -0
- package/dist/components/features/TaskSettings.js +83 -78
- package/dist/components/features/TaskSettings.test.js +171 -82
- package/dist/components/task/TaskActionHeader.js +11 -5
- package/dist/components/task/TaskActionHeader.test.js +10 -0
- package/dist/components/task/TaskCard.js +6 -2
- package/dist/components/task/TaskContextUpload.test.js +3 -3
- package/dist/components/task/TaskForm.js +14 -64
- package/dist/components/task/TaskKanban.js +0 -8
- package/dist/components/task/TaskList.js +5 -1
- package/dist/components/task/TaskList.test.js +4 -0
- package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
- package/dist/components/ui/HierarchyActionBadge.js +5 -0
- package/dist/components/views/AppShellHeader.d.ts +3 -1
- package/dist/components/views/AppShellHeader.js +27 -11
- package/dist/components/views/AppShellHeader.test.js +18 -1
- package/dist/components/views/PlanComparisonPage.d.ts +20 -15
- package/dist/components/views/PlanComparisonPage.js +221 -82
- package/dist/components/views/PlanComparisonPage.test.js +268 -14
- package/dist/components/views/PlansPage.js +16 -10
- package/dist/components/views/PlansPage.test.js +4 -2
- package/dist/components/views/StandaloneLayout.js +256 -69
- package/dist/components/views/WidgetView.js +10 -8
- package/dist/components/views/panels/PlanningDrawer.d.ts +19 -6
- package/dist/components/views/panels/PlanningDrawer.js +259 -51
- package/dist/components/views/panels/PlanningDrawer.test.js +392 -4
- package/dist/config/envSchema.js +1 -0
- package/dist/core/AiProfileService.d.ts +7 -0
- package/dist/core/AiProfileService.js +460 -35
- package/dist/core/AiProfiles.test.js +648 -2
- package/dist/core/AttachmentLinkService.d.ts +3 -0
- package/dist/core/AttachmentLinkService.js +58 -13
- package/dist/core/GlobalSettingsService.js +30 -0
- package/dist/core/GlobalSettingsService.test.d.ts +1 -0
- package/dist/core/GlobalSettingsService.test.js +45 -0
- package/dist/core/McpTokenService.d.ts +12 -0
- package/dist/core/McpTokenService.js +44 -1
- package/dist/core/PlanEntitlementService.d.ts +20 -0
- package/dist/core/PlanEntitlementService.js +215 -19
- package/dist/core/PlanFeatureCatalog.test.js +55 -0
- package/dist/core/PlanningEntities.test.js +366 -4
- package/dist/core/TaskActivityService.d.ts +28 -1
- package/dist/core/TaskActivityService.js +227 -46
- package/dist/core/TaskActivitySync.test.d.ts +1 -0
- package/dist/core/TaskActivitySync.test.js +90 -0
- package/dist/core/TaskAuditTimeline.test.js +96 -0
- package/dist/core/Taskforce.d.ts +204 -26
- package/dist/core/Taskforce.ids.test.js +58 -0
- package/dist/core/Taskforce.js +781 -71
- package/dist/core/Taskforce.mcpAuth.test.js +109 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +2 -1
- package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
- package/dist/hooks/bootstrapTimeouts.js +8 -0
- package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
- package/dist/hooks/bootstrapTimeouts.test.js +12 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +3 -3
- package/dist/hooks/sync/orchestratorShared.js +61 -1
- package/dist/hooks/sync/recovery.js +8 -0
- package/dist/hooks/sync/recovery.test.js +5 -5
- package/dist/hooks/sync/transfers.d.ts +2 -1
- package/dist/hooks/sync/transfers.js +36 -9
- package/dist/hooks/sync/transfers.test.js +534 -2
- package/dist/hooks/useFilterSort.js +13 -13
- package/dist/hooks/useFilterSort.test.js +87 -1
- package/dist/hooks/useSyncOrchestrator.js +50 -5
- package/dist/hooks/useTaskforce.d.ts +85 -50
- package/dist/hooks/useTaskforce.js +44 -14
- package/dist/hooks/useTaskforce.runtime-routing.test.js +94 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +99 -0
- package/dist/hooks/useWorkspaceSyncController.js +7 -1
- package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +14 -7
- package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
- package/dist/mcp/canonicalAssetHelpers.js +18 -10
- package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
- package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
- package/dist/mcp/clientIntegrations.d.ts +1 -0
- package/dist/mcp/clientIntegrations.js +25 -0
- package/dist/mcp/clientIntegrations.test.js +14 -3
- package/dist/mcp/clientProfileDefaults.js +3 -3
- package/dist/mcp/collaborationRegistrar.js +7 -7
- package/dist/mcp/documentAssetRegistrar.js +113 -7
- package/dist/mcp/runtime.d.ts +1 -0
- package/dist/mcp/runtime.js +969 -122
- package/dist/mcp/runtime.test.js +1083 -11
- package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
- package/dist/mcp/taskPlanningRegistrar.js +48 -0
- package/dist/mcp/toolRegistry.d.ts +56 -0
- package/dist/mcp/toolRegistry.js +8 -0
- package/dist/mcp/toolRegistry.test.js +4 -0
- package/dist/migrations/taskSchemaMigrations.js +58 -15
- package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
- package/dist/server/aiProfileAvatarAssets.js +319 -0
- package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
- package/dist/server/aiProfileAvatarAssets.test.js +213 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +66 -7
- package/dist/server/index.js +4 -0
- package/dist/server/index.test.js +6 -1
- package/dist/server/routes/admin.js +328 -9
- package/dist/server/routes/annotatedAttachments.js +51 -0
- package/dist/server/routes/auth.d.ts +11 -0
- package/dist/server/routes/auth.js +189 -27
- package/dist/server/routes/authSupport.d.ts +5 -0
- package/dist/server/routes/authSupport.js +13 -1
- package/dist/server/routes/billing.d.ts +1 -0
- package/dist/server/routes/billing.js +116 -63
- package/dist/server/routes/billing.test.js +162 -11
- package/dist/server/routes/documents.js +10 -0
- package/dist/server/routes/shared.js +0 -10
- package/dist/server/routes/sync.integration.test.js +221 -0
- package/dist/server/routes/sync.js +13 -3
- package/dist/server/routes/syncSnapshotRoutes.js +2 -0
- package/dist/server/routes/tasks.js +12 -9
- package/dist/server/routes.js +87 -8
- package/dist/server/routes.test.js +972 -23
- package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
- package/dist/shared/aiProfileSurfaceType.js +10 -8
- package/dist/storage/objectStorage.d.ts +1 -0
- package/dist/storage/objectStorage.js +2 -1
- package/dist/storage/objectStorageClient.d.ts +1 -0
- package/dist/storage/objectStorageClient.js +41 -8
- package/dist/storage/objectStorageClient.test.js +26 -1
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.js +13 -1
- package/dist/sync/collaborationSyncPayload.js +2 -0
- package/dist/sync/collaborationSyncPayload.test.js +1 -0
- package/dist/sync/collaborationSyncState.d.ts +3 -3
- package/dist/sync/collaborationSyncState.js +19 -12
- package/dist/sync/contentSyncPayload.d.ts +5 -1
- package/dist/sync/contentSyncPayload.js +9 -0
- package/dist/sync/contentSyncPayload.test.js +39 -0
- package/dist/sync/contentSyncState.d.ts +5 -1
- package/dist/sync/contentSyncState.js +231 -37
- package/dist/sync/planningSyncPayload.js +5 -0
- package/dist/sync/planningSyncPayload.test.js +24 -0
- package/dist/sync/syncApplyHandlers.d.ts +4 -4
- package/dist/sync/syncApplyHandlers.js +89 -31
- package/dist/sync/syncApplyHandlers.test.js +184 -4
- package/dist/sync/syncResourceAdapters.d.ts +2 -0
- package/dist/sync/syncResourceAdapters.js +2 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/syncService.test.js +39 -0
- package/dist/sync/workspacePullFeed.d.ts +4 -0
- package/dist/sync/workspacePullFeed.js +129 -70
- package/dist/sync/workspacePullFeed.test.js +49 -0
- package/dist/sync/workspaceSyncModel.d.ts +28 -6
- package/dist/sync/workspaceSyncModel.js +159 -45
- package/dist/sync/workspaceSyncModel.test.js +269 -3
- package/dist/types.d.ts +33 -2
- package/dist/ui/agent-logos/ChatGPT.png +0 -0
- package/dist/ui/agent-logos/Gemini CLI.jpeg +0 -0
- package/dist/ui/agent-logos/antigravity.jpeg +0 -0
- package/dist/ui/agent-logos/claude-code.jpeg +0 -0
- package/dist/ui/agent-logos/codex.jpeg +0 -0
- package/dist/ui/agent-logos/cursor.png +0 -0
- package/dist/ui/agent-logos/openclaw.jpeg +0 -0
- package/dist/ui/agent-logos/windsurf.png +0 -0
- package/dist/ui/assets/AgentsModule-BS4Pi_nC.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CCckzWYZ.js +3 -0
- package/dist/ui/assets/ContextAttachmentManager-CfG_ER7C.js +3 -0
- package/dist/ui/assets/DocumentWorkspace-BVaWPA25.js +252 -0
- package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
- package/dist/ui/assets/EntityActivityTimeline-DSj0ThaK.js +1 -0
- package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
- package/dist/ui/assets/{InitiativesModule-9E6ParrY.js → InitiativesModule-AxMkWtxH.js} +1 -1
- package/dist/ui/assets/PlansPage-B_z-D6Nh.css +1 -0
- package/dist/ui/assets/PlansPage-Ndt7mYfo.js +1 -0
- package/dist/ui/assets/TaskContextUpload-Dw4rTF4i.js +1 -0
- package/dist/ui/assets/TaskSettings-f2ga42_V.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-BA7jcEpH.js → WorkflowsModule-E4UL3mov.js} +4 -4
- package/dist/ui/assets/documentReferences-BOUcJm6-.js +1 -0
- package/dist/ui/assets/index-BvAbqx5Q.css +1 -0
- package/dist/ui/assets/index-MAHKvFqp.js +4 -0
- package/dist/ui/assets/{vendor-icons-DuEd_65c.js → vendor-icons-B32hGuF2.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/og-image.png +0 -0
- package/dist/ui/product/agent manager.png +0 -0
- package/dist/ui/product/agent_manager_02.png +0 -0
- package/dist/utils/aiProfileEvents.d.ts +7 -0
- package/dist/utils/aiProfileEvents.js +6 -0
- package/dist/utils/assignees.d.ts +6 -0
- package/dist/utils/assignees.js +8 -1
- package/dist/utils/assignees.test.d.ts +1 -0
- package/dist/utils/assignees.test.js +25 -0
- package/dist/utils/avatarDisplay.d.ts +1 -0
- package/dist/utils/avatarDisplay.js +15 -0
- package/dist/utils/contextFiles.d.ts +3 -1
- package/dist/utils/contextFiles.js +2 -1
- package/dist/utils/taskActivity.d.ts +7 -1
- package/dist/utils/taskActivity.js +63 -1
- package/dist/utils/taskActivity.test.js +23 -1
- package/dist/utils/taskSearch.d.ts +22 -0
- package/dist/utils/taskSearch.js +87 -0
- package/dist/utils/taskSearch.test.d.ts +1 -0
- package/dist/utils/taskSearch.test.js +69 -0
- package/dist/utils/taskUtils.js +10 -3
- package/dist/utils/taskUtils.test.d.ts +1 -0
- package/dist/utils/taskUtils.test.js +19 -0
- package/package.json +1 -1
- package/dist/ui/assets/AgentsModule-DrLawwNl.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-Z9_whf7F.js +0 -3
- package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +0 -252
- package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +0 -1
- package/dist/ui/assets/PlansPage-CvfnMiWq.css +0 -1
- package/dist/ui/assets/PlansPage-DRXscYxH.js +0 -1
- package/dist/ui/assets/TaskSettings-DZX4jk7e.js +0 -9
- package/dist/ui/assets/index-9eT8e0Lu.css +0 -1
- package/dist/ui/assets/index-C6k75jr8.js +0 -6
|
@@ -60,6 +60,8 @@ import { getRouteTimingNow, logSlowBootstrapRoute, requestBootstrapTraceId, requ
|
|
|
60
60
|
import { listBuiltInCustomTaxonomyLibraryPacks } from '../../shared/customTaxonomyLibrary.js';
|
|
61
61
|
import { listBuiltInTaxonomyLibraryPacks } from '../../shared/taxonomyLibrary.js';
|
|
62
62
|
import { shouldUseProvisionalTaskReferences } from '../../utils/taskReferences.js';
|
|
63
|
+
// === SECTION: Module dependency interface ===
|
|
64
|
+
const UI_STATE_MAX_JSON_BODY_BYTES = 50 * 1024 * 1024;
|
|
63
65
|
function createUiStateRequestId() {
|
|
64
66
|
return `ui-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
65
67
|
}
|
|
@@ -237,8 +239,9 @@ export function registerTaskRoutes(deps) {
|
|
|
237
239
|
const requestId = createUiStateRequestId();
|
|
238
240
|
const startedAt = Date.now();
|
|
239
241
|
attachUiStateDebugHeaders(res, requestId);
|
|
240
|
-
|
|
242
|
+
let body = {};
|
|
241
243
|
try {
|
|
244
|
+
body = await parseJsonBody(req, UI_STATE_MAX_JSON_BODY_BYTES);
|
|
242
245
|
const requestedWorkspaceId = String(body?.workspaceId || '').trim();
|
|
243
246
|
let workspaceId = requestWorkspaceId(req);
|
|
244
247
|
if (requestedWorkspaceId && requestRuntimeMode(req) === 'local') {
|
|
@@ -555,7 +558,7 @@ export function registerTaskRoutes(deps) {
|
|
|
555
558
|
const body = await parseJsonBody(req);
|
|
556
559
|
try {
|
|
557
560
|
const workspaceId = requestWorkspaceId(req);
|
|
558
|
-
const initiative = core.createInitiative(body || {}, workspaceId);
|
|
561
|
+
const initiative = core.createInitiative(body || {}, workspaceId, { actorRef: 'user' });
|
|
559
562
|
res.writeHead(201, { 'Content-Type': 'application/json' });
|
|
560
563
|
res.end(JSON.stringify(initiative));
|
|
561
564
|
}
|
|
@@ -587,7 +590,7 @@ export function registerTaskRoutes(deps) {
|
|
|
587
590
|
const body = await parseJsonBody(req);
|
|
588
591
|
try {
|
|
589
592
|
const workspaceId = requestWorkspaceId(req);
|
|
590
|
-
const updated = core.updateInitiative(params.id, body || {}, workspaceId);
|
|
593
|
+
const updated = core.updateInitiative(params.id, body || {}, workspaceId, { actorRef: 'user' });
|
|
591
594
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
592
595
|
res.end(JSON.stringify(updated));
|
|
593
596
|
}
|
|
@@ -603,7 +606,7 @@ export function registerTaskRoutes(deps) {
|
|
|
603
606
|
return;
|
|
604
607
|
try {
|
|
605
608
|
const workspaceId = requestWorkspaceId(req);
|
|
606
|
-
const archived = core.archiveInitiative(params.id, workspaceId);
|
|
609
|
+
const archived = core.archiveInitiative(params.id, workspaceId, { actorRef: 'user' });
|
|
607
610
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
608
611
|
res.end(JSON.stringify(archived));
|
|
609
612
|
}
|
|
@@ -619,7 +622,7 @@ export function registerTaskRoutes(deps) {
|
|
|
619
622
|
return;
|
|
620
623
|
try {
|
|
621
624
|
const workspaceId = requestWorkspaceId(req);
|
|
622
|
-
const restored = core.unarchiveInitiative(params.id, workspaceId);
|
|
625
|
+
const restored = core.unarchiveInitiative(params.id, workspaceId, { actorRef: 'user' });
|
|
623
626
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
624
627
|
res.end(JSON.stringify(restored));
|
|
625
628
|
}
|
|
@@ -646,7 +649,7 @@ export function registerTaskRoutes(deps) {
|
|
|
646
649
|
const body = await parseJsonBody(req);
|
|
647
650
|
try {
|
|
648
651
|
const workspaceId = requestWorkspaceId(req);
|
|
649
|
-
const workstream = core.createWorkstream(body || {}, workspaceId);
|
|
652
|
+
const workstream = core.createWorkstream(body || {}, workspaceId, { actorRef: 'user' });
|
|
650
653
|
res.writeHead(201, { 'Content-Type': 'application/json' });
|
|
651
654
|
res.end(JSON.stringify(workstream));
|
|
652
655
|
}
|
|
@@ -678,7 +681,7 @@ export function registerTaskRoutes(deps) {
|
|
|
678
681
|
const body = await parseJsonBody(req);
|
|
679
682
|
try {
|
|
680
683
|
const workspaceId = requestWorkspaceId(req);
|
|
681
|
-
const updated = core.updateWorkstream(params.id, body || {}, workspaceId);
|
|
684
|
+
const updated = core.updateWorkstream(params.id, body || {}, workspaceId, { actorRef: 'user' });
|
|
682
685
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
683
686
|
res.end(JSON.stringify(updated));
|
|
684
687
|
}
|
|
@@ -694,7 +697,7 @@ export function registerTaskRoutes(deps) {
|
|
|
694
697
|
return;
|
|
695
698
|
try {
|
|
696
699
|
const workspaceId = requestWorkspaceId(req);
|
|
697
|
-
const archived = core.archiveWorkstream(params.id, workspaceId);
|
|
700
|
+
const archived = core.archiveWorkstream(params.id, workspaceId, { actorRef: 'user' });
|
|
698
701
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
699
702
|
res.end(JSON.stringify(archived));
|
|
700
703
|
}
|
|
@@ -710,7 +713,7 @@ export function registerTaskRoutes(deps) {
|
|
|
710
713
|
return;
|
|
711
714
|
try {
|
|
712
715
|
const workspaceId = requestWorkspaceId(req);
|
|
713
|
-
const restored = core.unarchiveWorkstream(params.id, workspaceId);
|
|
716
|
+
const restored = core.unarchiveWorkstream(params.id, workspaceId, { actorRef: 'user' });
|
|
714
717
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
715
718
|
res.end(JSON.stringify(restored));
|
|
716
719
|
}
|
package/dist/server/routes.js
CHANGED
|
@@ -111,13 +111,14 @@ function resolveErrorStatusCode(error, fallback = 400) {
|
|
|
111
111
|
}
|
|
112
112
|
return fallback;
|
|
113
113
|
}
|
|
114
|
-
function writeMcpHttpError(res, statusCode, message) {
|
|
114
|
+
function writeMcpHttpError(res, statusCode, message, data) {
|
|
115
115
|
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
116
116
|
res.end(JSON.stringify({
|
|
117
117
|
jsonrpc: '2.0',
|
|
118
118
|
error: {
|
|
119
119
|
code: -32000,
|
|
120
120
|
message,
|
|
121
|
+
...(data ? { data } : {}),
|
|
121
122
|
},
|
|
122
123
|
id: null,
|
|
123
124
|
}));
|
|
@@ -522,7 +523,10 @@ export function createRoutes(core, context = {}) {
|
|
|
522
523
|
const primaryLink = canonicalAsset?.assetId
|
|
523
524
|
? workspaceAssetStore?.listLinksForAsset(canonicalAsset.assetId, inferWorkspaceIdFromStoragePath(normalizedStorageKey)).find((entry) => !entry.deletedAt && (!opts?.taskId || entry.taskId === opts.taskId))
|
|
524
525
|
: null;
|
|
526
|
+
const isExplicitTaskAttachment = typeof opts?.taskId === 'string' && opts.taskId.trim().length > 0;
|
|
525
527
|
const timestamp = String(opts?.timestamp
|
|
528
|
+
|| primaryLink?.updatedAt
|
|
529
|
+
|| (isExplicitTaskAttachment ? new Date().toISOString() : null)
|
|
526
530
|
|| canonicalAsset?.updatedAt
|
|
527
531
|
|| canonicalAsset?.createdAt
|
|
528
532
|
|| new Date().toISOString()).trim() || new Date().toISOString();
|
|
@@ -567,6 +571,45 @@ export function createRoutes(core, context = {}) {
|
|
|
567
571
|
taskId
|
|
568
572
|
};
|
|
569
573
|
};
|
|
574
|
+
const taskHasAttachmentForAsset = (task, asset) => {
|
|
575
|
+
if (!task || !Array.isArray(task.attachments))
|
|
576
|
+
return false;
|
|
577
|
+
const canonicalDocumentPath = `/api/taskforce/documents/${encodeURIComponent(asset.assetId)}/content`;
|
|
578
|
+
const contextPath = `/api/taskforce/context/${encodeURIComponent(asset.storageKey)}`;
|
|
579
|
+
return task.attachments.some((attachment) => {
|
|
580
|
+
if (typeof attachment === 'string') {
|
|
581
|
+
return attachment === canonicalDocumentPath
|
|
582
|
+
|| attachment === contextPath
|
|
583
|
+
|| attachment === asset.storageKey;
|
|
584
|
+
}
|
|
585
|
+
if (!attachment || typeof attachment !== 'object')
|
|
586
|
+
return false;
|
|
587
|
+
return attachment.assetId === asset.assetId
|
|
588
|
+
|| attachment.fsPath === asset.storageKey
|
|
589
|
+
|| attachment.path === canonicalDocumentPath
|
|
590
|
+
|| attachment.path === contextPath;
|
|
591
|
+
});
|
|
592
|
+
};
|
|
593
|
+
const recordTaskAttachmentActivity = (input) => {
|
|
594
|
+
const afterTask = core.getTask(input.taskId, input.workspaceId);
|
|
595
|
+
if (!taskHasAttachmentForAsset(afterTask, input.asset))
|
|
596
|
+
return;
|
|
597
|
+
core.recordTaskEvent({
|
|
598
|
+
taskId: input.taskId,
|
|
599
|
+
workspaceId: input.workspaceId,
|
|
600
|
+
action: 'task-attachments-changed',
|
|
601
|
+
actor: 'user',
|
|
602
|
+
createdAt: input.createdAt || new Date().toISOString(),
|
|
603
|
+
details: {
|
|
604
|
+
changes: {
|
|
605
|
+
attachments: {
|
|
606
|
+
from: input.beforeTask.attachments || [],
|
|
607
|
+
to: afterTask?.attachments || [],
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
};
|
|
570
613
|
const sanitizeDownloadFilename = (nameRaw, fallback = 'download') => {
|
|
571
614
|
const normalized = String(nameRaw || '').trim()
|
|
572
615
|
.replace(/[\\/:*?"<>|]/g, '-')
|
|
@@ -660,6 +703,8 @@ export function createRoutes(core, context = {}) {
|
|
|
660
703
|
purgeAfter: null
|
|
661
704
|
});
|
|
662
705
|
const taskId = String(params.taskId || inferTaskIdFromStoragePath(params.relativeToStorage) || '').trim();
|
|
706
|
+
const taskBeforeLink = taskId ? core.getTask(taskId, workspaceId) : null;
|
|
707
|
+
const wasAttachedBefore = taskHasAttachmentForAsset(taskBeforeLink, asset);
|
|
663
708
|
if (taskId) {
|
|
664
709
|
workspaceAssetStore.upsertLink({
|
|
665
710
|
workspaceId,
|
|
@@ -669,6 +714,15 @@ export function createRoutes(core, context = {}) {
|
|
|
669
714
|
displayName: null,
|
|
670
715
|
deletedAt: null
|
|
671
716
|
});
|
|
717
|
+
if (taskBeforeLink && !wasAttachedBefore) {
|
|
718
|
+
recordTaskAttachmentActivity({
|
|
719
|
+
taskId,
|
|
720
|
+
workspaceId,
|
|
721
|
+
asset,
|
|
722
|
+
beforeTask: taskBeforeLink,
|
|
723
|
+
createdAt: asset.updatedAt,
|
|
724
|
+
});
|
|
725
|
+
}
|
|
672
726
|
}
|
|
673
727
|
core.notifyDocumentMetadataMutation(workspaceId, [params.relativeToStorage], 'upsert');
|
|
674
728
|
}
|
|
@@ -1146,6 +1200,8 @@ export function createRoutes(core, context = {}) {
|
|
|
1146
1200
|
authenticatedViaOAuth: oauthAuth || null,
|
|
1147
1201
|
userId: null,
|
|
1148
1202
|
...bootstrap,
|
|
1203
|
+
aiProfileToken: bootstrap.aiProfileToken || oauthAuth?.aiProfileToken || null,
|
|
1204
|
+
aiProfileName: bootstrap.aiProfileName || oauthAuth?.aiProfileName || null,
|
|
1149
1205
|
};
|
|
1150
1206
|
}
|
|
1151
1207
|
core.addMcpAuditLog({
|
|
@@ -1385,6 +1441,7 @@ export function createRoutes(core, context = {}) {
|
|
|
1385
1441
|
return;
|
|
1386
1442
|
}
|
|
1387
1443
|
const authScopes = auth.authenticatedViaToken?.scopes || auth.authenticatedViaOAuth?.scopes || [];
|
|
1444
|
+
const requestId = String(req.headers['x-request-id'] || req.headers['x-railway-request-id'] || '').trim() || randomUUID();
|
|
1388
1445
|
const deniedToolName = findDeniedCloudMcpToolName(body, authScopes);
|
|
1389
1446
|
if (deniedToolName) {
|
|
1390
1447
|
core.addMcpAuditLog({
|
|
@@ -1394,7 +1451,7 @@ export function createRoutes(core, context = {}) {
|
|
|
1394
1451
|
tokenId: auth.authenticatedViaToken?.tokenId || auth.authenticatedViaOAuth?.grantId || null,
|
|
1395
1452
|
toolName: deniedToolName,
|
|
1396
1453
|
details: {
|
|
1397
|
-
requestId
|
|
1454
|
+
requestId,
|
|
1398
1455
|
ip: req.socket?.remoteAddress || null,
|
|
1399
1456
|
userAgent: requestHeader(req, 'user-agent', '') || null,
|
|
1400
1457
|
outcome: 'deny',
|
|
@@ -1408,11 +1465,13 @@ export function createRoutes(core, context = {}) {
|
|
|
1408
1465
|
if (!applyCloudMcpWriteRateLimit(req, res, auth, body)) {
|
|
1409
1466
|
return;
|
|
1410
1467
|
}
|
|
1468
|
+
let runtime = null;
|
|
1411
1469
|
try {
|
|
1412
|
-
|
|
1470
|
+
runtime = createTaskforceMcpServer({
|
|
1413
1471
|
projectRoot: core.getPaths().projectRoot,
|
|
1414
1472
|
tenantId: core.getTenantId(),
|
|
1415
1473
|
workspaceId: auth.workspaceId,
|
|
1474
|
+
core: core,
|
|
1416
1475
|
serverName: 'taskforce-cloud',
|
|
1417
1476
|
logStartup: false,
|
|
1418
1477
|
runtimeMode: 'cloud',
|
|
@@ -1420,7 +1479,7 @@ export function createRoutes(core, context = {}) {
|
|
|
1420
1479
|
req,
|
|
1421
1480
|
auth,
|
|
1422
1481
|
requestHeader,
|
|
1423
|
-
requestId
|
|
1482
|
+
requestId,
|
|
1424
1483
|
authScopes,
|
|
1425
1484
|
}),
|
|
1426
1485
|
});
|
|
@@ -1435,13 +1494,29 @@ export function createRoutes(core, context = {}) {
|
|
|
1435
1494
|
}
|
|
1436
1495
|
await transport.handleRequest(req, res, body);
|
|
1437
1496
|
recordCloudMcpCredentialUsage(req, auth.authenticatedViaToken, auth.authenticatedViaOAuth);
|
|
1438
|
-
await transport.close().catch(() => undefined);
|
|
1439
|
-
await runtime.server.close().catch(() => undefined);
|
|
1440
1497
|
}
|
|
1441
1498
|
catch (error) {
|
|
1442
|
-
console.error('[Taskforce MCP] Cloud transport request failed:',
|
|
1499
|
+
console.error('[Taskforce MCP] Cloud transport request failed:', {
|
|
1500
|
+
requestId,
|
|
1501
|
+
kind: 'tool_transport_failure',
|
|
1502
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1503
|
+
});
|
|
1443
1504
|
if (!res.headersSent) {
|
|
1444
|
-
writeMcpHttpError(res, 500, '
|
|
1505
|
+
writeMcpHttpError(res, 500, 'MCP transport failure.', {
|
|
1506
|
+
kind: 'tool_transport_failure',
|
|
1507
|
+
retryable: true,
|
|
1508
|
+
requestId,
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
finally {
|
|
1513
|
+
if (runtime) {
|
|
1514
|
+
try {
|
|
1515
|
+
await runtime.server.close();
|
|
1516
|
+
}
|
|
1517
|
+
catch (closeError) {
|
|
1518
|
+
console.warn('[Taskforce MCP] Cloud transport cleanup failed:', closeError);
|
|
1519
|
+
}
|
|
1445
1520
|
}
|
|
1446
1521
|
}
|
|
1447
1522
|
};
|
|
@@ -1531,6 +1606,10 @@ export function createRoutes(core, context = {}) {
|
|
|
1531
1606
|
resolveAdminRequestActor,
|
|
1532
1607
|
resolveEffectiveObjectStorageConfig,
|
|
1533
1608
|
getObjectStorageClient,
|
|
1609
|
+
workspaceAssetStore,
|
|
1610
|
+
ensureWithinDir,
|
|
1611
|
+
markAssetDeleted,
|
|
1612
|
+
appendStorageTelemetry,
|
|
1534
1613
|
});
|
|
1535
1614
|
registerWorkspaceRoutes({
|
|
1536
1615
|
addRoute,
|