@taskforcehq/taskforce 0.3.302 → 0.3.304
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 +113 -5
- package/dist/TaskforceCore.js +560 -208
- package/dist/TaskforceCore.test.js +1833 -91
- package/dist/annotatedAttachments/service.d.ts +1 -1
- package/dist/annotatedAttachments/types.d.ts +1 -1
- package/dist/components/features/AgentsModule.js +1 -1
- package/dist/components/features/AgentsModule.test.js +1 -1
- package/dist/components/features/TaskSettings.js +58 -38
- package/dist/components/features/TaskSettings.test.js +139 -40
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +3 -3
- package/dist/components/task/TaskActionHeader.test.js +8 -0
- package/dist/components/task/TaskCard.js +16 -1
- package/dist/components/task/TaskCard.test.js +31 -0
- package/dist/components/task/TaskForm.d.ts +2 -1
- package/dist/components/task/TaskForm.js +22 -4
- package/dist/components/task/TaskForm.test.js +46 -0
- package/dist/components/task/TaskKanban.d.ts +1 -1
- package/dist/components/task/TaskKanban.js +31 -160
- package/dist/components/task/TaskKanban.test.js +17 -0
- package/dist/components/task/TaskStatusActions.d.ts +6 -1
- package/dist/components/task/TaskStatusActions.js +8 -3
- package/dist/components/task/TaskStatusActions.test.js +9 -0
- package/dist/components/task/taskKanbanDropRules.d.ts +58 -0
- package/dist/components/task/taskKanbanDropRules.js +187 -0
- package/dist/components/task/taskKanbanDropRules.test.d.ts +1 -0
- package/dist/components/task/taskKanbanDropRules.test.js +114 -0
- package/dist/components/ui/Modal.d.ts +1 -1
- package/dist/components/ui/Modal.js +1 -0
- package/dist/components/views/AppShellHeader.js +5 -1
- package/dist/components/views/AppShellHeader.test.js +4 -0
- package/dist/components/views/PlanComparisonPage.d.ts +3 -2
- package/dist/components/views/PlanComparisonPage.js +4 -2
- package/dist/components/views/PlanComparisonPage.test.js +4 -0
- package/dist/components/views/PlansPage.d.ts +7 -1
- package/dist/components/views/PlansPage.js +139 -53
- package/dist/components/views/PlansPage.test.d.ts +1 -0
- package/dist/components/views/PlansPage.test.js +157 -0
- package/dist/components/views/StandaloneLayout.d.ts +1 -0
- package/dist/components/views/StandaloneLayout.js +216 -186
- package/dist/components/views/WidgetView.js +11 -2
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +8 -3
- package/dist/components/views/standalone/modals/AccountHubModal.js +16 -2
- package/dist/components/views/standalone/modals/AccountHubModal.test.d.ts +1 -0
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +26 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.js +1 -1
- package/dist/core/DeletedTaskLifecycleService.d.ts +2 -1
- package/dist/core/EntitlementsPolicy.test.js +2 -2
- package/dist/core/GlobalSettingsService.js +78 -18
- package/dist/core/PlanEntitlementService.d.ts +31 -5
- package/dist/core/PlanEntitlementService.js +350 -222
- package/dist/core/SignupMonetizationSettings.test.js +208 -49
- package/dist/core/SystemAdmin.test.js +186 -96
- package/dist/core/TaskActivityService.d.ts +4 -1
- package/dist/core/TaskActivityService.js +45 -0
- package/dist/core/TaskAuditTimeline.test.js +52 -1
- package/dist/core/Taskforce.d.ts +65 -20
- package/dist/core/Taskforce.js +261 -51
- package/dist/core/Taskforce.mcpAuth.test.js +0 -2
- package/dist/core/UserProfileAvatarDrafts.test.js +12 -3
- package/dist/core/WorkspacePlanMode.test.js +65 -0
- package/dist/core/types.d.ts +11 -12
- package/dist/documentReviews/service.d.ts +1 -1
- package/dist/documentReviews/types.d.ts +1 -1
- package/dist/hooks/auth/useTaskforceAuthBootstrap.d.ts +48 -0
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +219 -0
- package/dist/hooks/sync/auth.d.ts +37 -0
- package/dist/hooks/sync/auth.js +61 -0
- package/dist/hooks/sync/bootstrap.d.ts +34 -0
- package/dist/hooks/sync/bootstrap.js +52 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +36 -0
- package/dist/hooks/sync/orchestratorShared.js +209 -0
- package/dist/hooks/sync/orchestratorShared.test.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.test.js +49 -0
- package/dist/hooks/sync/realtime.d.ts +25 -0
- package/dist/hooks/sync/realtime.js +60 -0
- package/dist/hooks/sync/recovery.d.ts +69 -0
- package/dist/hooks/sync/recovery.js +118 -0
- package/dist/hooks/sync/transfers.d.ts +122 -0
- package/dist/hooks/sync/transfers.js +431 -0
- package/dist/hooks/sync/useDataVersionRefresh.d.ts +16 -0
- package/dist/hooks/sync/useDataVersionRefresh.js +73 -0
- package/dist/hooks/ui/useResourceExport.d.ts +3 -1
- package/dist/hooks/ui/useResourceExport.js +5 -2
- package/dist/hooks/ui/useWorkflowTemplates.js +11 -6
- package/dist/hooks/useRealtimeSync.js +2 -1
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +8 -0
- package/dist/hooks/useSyncOrchestrator.context-assets.test.d.ts +1 -0
- package/dist/hooks/useSyncOrchestrator.context-assets.test.js +228 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +5 -4
- package/dist/hooks/useSyncOrchestrator.js +315 -860
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +665 -8
- package/dist/hooks/useTaskMutations.js +45 -6
- package/dist/hooks/useTaskMutations.test.js +147 -0
- package/dist/hooks/useTaskforce.d.ts +11 -2
- package/dist/hooks/useTaskforce.js +290 -812
- package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
- package/dist/hooks/useWorkspaceSyncController.js +22 -10
- package/dist/hooks/workspace/useTaskforceApiRouting.test.js +17 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +166 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +434 -0
- package/dist/hooks/workspace/workspaceLocalState.d.ts +19 -0
- package/dist/hooks/workspace/workspaceLocalState.js +100 -0
- package/dist/hooks/workspace/workspaceLocalState.test.d.ts +1 -0
- package/dist/hooks/workspace/workspaceLocalState.test.js +59 -0
- package/dist/localization/locales/en-US.js +2 -2
- package/dist/mcp/canonicalAssetHelpers.d.ts +70 -0
- package/dist/mcp/canonicalAssetHelpers.js +259 -0
- package/dist/mcp/clientIntegrations.d.ts +12 -1
- package/dist/mcp/clientIntegrations.js +161 -6
- package/dist/mcp/clientIntegrations.test.js +76 -4
- package/dist/mcp/documentHelpers.d.ts +100 -0
- package/dist/mcp/documentHelpers.js +161 -0
- package/dist/mcp/runtime.js +264 -505
- package/dist/mcp/runtime.test.js +353 -89
- package/dist/mcp/taskAttachmentHelpers.d.ts +41 -0
- package/dist/mcp/taskAttachmentHelpers.js +60 -0
- package/dist/mcp/taskAttachmentTypes.d.ts +37 -0
- package/dist/mcp/taskAttachmentTypes.js +1 -0
- package/dist/migrations/billingSchemaParity.test.js +3 -0
- package/dist/migrations/taskSchemaMigrations.js +15 -0
- package/dist/plugins/vite.js +1 -1
- package/dist/runtime/appGateDefinitions.d.ts +1 -1
- package/dist/runtime/appGateDefinitions.js +1 -1
- package/dist/server/index.cookieProxy.test.js +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +48 -3
- package/dist/server/index.test.js +14 -2
- package/dist/server/mockStripe.d.ts +1 -0
- package/dist/server/mockStripe.js +2 -0
- package/dist/server/routes/admin.js +91 -40
- package/dist/server/routes/auth.d.ts +1 -0
- package/dist/server/routes/auth.js +231 -55
- package/dist/server/routes/billing.js +473 -39
- package/dist/server/routes/billing.test.js +972 -37
- package/dist/server/routes/shared.d.ts +30 -0
- package/dist/server/routes/shared.js +31 -3
- package/dist/server/routes/sync.integration.test.js +180 -0
- package/dist/server/routes/sync.js +125 -242
- package/dist/server/routes/tasks.js +49 -7
- package/dist/server/routes.js +11 -22
- package/dist/server/routes.test.js +530 -81
- package/dist/shared/taskActor.d.ts +10 -0
- package/dist/shared/taskActor.js +1 -0
- package/dist/sync/cloudSyncApi.d.ts +1 -0
- package/dist/sync/collaborationSyncPayload.js +4 -0
- package/dist/sync/collaborationSyncPayload.test.js +8 -0
- package/dist/sync/collaborationSyncState.d.ts +3 -1
- package/dist/sync/collaborationSyncState.js +19 -0
- package/dist/sync/contentSyncState.d.ts +10 -0
- package/dist/sync/contentSyncState.js +277 -14
- package/dist/sync/syncApplyHandlers.d.ts +87 -1
- package/dist/sync/syncApplyHandlers.js +370 -8
- package/dist/sync/syncApplyHandlers.test.d.ts +1 -0
- package/dist/sync/syncApplyHandlers.test.js +377 -0
- package/dist/sync/syncService.d.ts +9 -1
- package/dist/sync/syncService.js +57 -10
- package/dist/sync/syncService.test.js +48 -0
- package/dist/sync/workspacePullFeed.d.ts +11 -0
- package/dist/sync/workspacePullFeed.js +123 -68
- package/dist/sync/workspacePullFeed.test.js +180 -0
- package/dist/sync/workspaceSyncModel.d.ts +22 -1
- package/dist/sync/workspaceSyncModel.js +65 -0
- package/dist/sync/workspaceSyncModel.test.js +119 -0
- package/dist/types.d.ts +2 -10
- package/dist/ui/assets/AgentsModule-BLWVbuKP.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-Dvi02Y7q.js → AnnotatedAttachmentWorkspace-BlS-cqnl.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-iys3zfca.js → DocumentWorkspace-BH_6DF6x.js} +1 -1
- package/dist/ui/assets/{InitiativesModule-DJvLJI3A.js → InitiativesModule-BjR6iBf9.js} +1 -1
- package/dist/ui/assets/{PlansPage-BlVC_lRq.css → PlansPage-C2dd2n1X.css} +1 -1
- package/dist/ui/assets/PlansPage-CSDQ4sLa.js +1 -0
- package/dist/ui/assets/TaskSettings-CEDy34Jo.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-BguHeQaV.js → WorkflowsModule-DnFqdUME.js} +1 -1
- package/dist/ui/assets/index-DXUdtH1B.js +6 -0
- package/dist/ui/assets/index-Ii0B0rTO.css +1 -0
- package/dist/ui/assets/{vendor-icons-C8EED3Oh.js → vendor-icons-I7ZwG1z_.js} +1 -1
- package/dist/ui/index.html +4 -4
- package/dist/utils/accountProfileSummaryCache.d.ts +31 -0
- package/dist/utils/accountProfileSummaryCache.js +97 -0
- package/dist/utils/accountProfileSummaryCache.test.d.ts +1 -0
- package/dist/utils/accountProfileSummaryCache.test.js +63 -0
- package/dist/utils/taskActivity.js +4 -0
- package/dist/utils/taskActivity.test.js +25 -1
- package/package.json +5 -3
- package/scripts/playwright-auth.sh +4 -0
- package/dist/ui/assets/AgentsModule-JG5jc3he.js +0 -1
- package/dist/ui/assets/PlansPage-BMPlpFpw.js +0 -1
- package/dist/ui/assets/TaskSettings-Bqd4cCzW.js +0 -8
- package/dist/ui/assets/index-MXeWoebC.css +0 -1
- package/dist/ui/assets/index-YJ4k5QNa.js +0 -6
- package/dist/utils/billingStatusCache.d.ts +0 -21
- package/dist/utils/billingStatusCache.js +0 -70
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { WorkspaceAssetEntry, WorkspaceAssetStore } from '../storage/workspaceAssetStore.js';
|
|
2
|
+
export interface DocumentHelpersDeps {
|
|
3
|
+
activeWorkspaceId: string;
|
|
4
|
+
workspaceAssetStore: WorkspaceAssetStore | null;
|
|
5
|
+
getDocumentReferenceLabel: (asset: {
|
|
6
|
+
assetId: string;
|
|
7
|
+
documentId?: string | null;
|
|
8
|
+
referenceNumber?: number | null;
|
|
9
|
+
}) => string | null;
|
|
10
|
+
parseDocumentReference: (value: string) => number | null;
|
|
11
|
+
isTextReadableMimeType: (mimeTypeRaw: string) => boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function createDocumentHelpers(deps: DocumentHelpersDeps): {
|
|
14
|
+
buildDocumentDescriptor: (asset: {
|
|
15
|
+
assetId: string;
|
|
16
|
+
documentId: string | null;
|
|
17
|
+
referenceNumber?: number | null;
|
|
18
|
+
kind?: string | null;
|
|
19
|
+
logicalName?: string | null;
|
|
20
|
+
originalFilename?: string | null;
|
|
21
|
+
version?: number | null;
|
|
22
|
+
storageKey?: string | null;
|
|
23
|
+
mimeType?: string | null;
|
|
24
|
+
sizeBytes?: number | null;
|
|
25
|
+
updatedAt?: string | null;
|
|
26
|
+
}) => {
|
|
27
|
+
assetId: string;
|
|
28
|
+
documentId: string | null;
|
|
29
|
+
referenceNumber: number | null;
|
|
30
|
+
referenceLabel: string | null;
|
|
31
|
+
logicalName: string | null;
|
|
32
|
+
originalFilename: string | null;
|
|
33
|
+
version: number | null;
|
|
34
|
+
storageKey: string | null;
|
|
35
|
+
mimeType: string | null;
|
|
36
|
+
sizeBytes: number | null;
|
|
37
|
+
updatedAt: string | null;
|
|
38
|
+
apiUrl: string;
|
|
39
|
+
};
|
|
40
|
+
buildDocumentReadHint: (asset: {
|
|
41
|
+
assetId: string;
|
|
42
|
+
documentId: string | null;
|
|
43
|
+
referenceNumber?: number | null;
|
|
44
|
+
mimeType?: string | null;
|
|
45
|
+
}) => {
|
|
46
|
+
available: boolean;
|
|
47
|
+
nextTool: string;
|
|
48
|
+
suggestedArgs: {
|
|
49
|
+
documentId: string;
|
|
50
|
+
};
|
|
51
|
+
guidance: string;
|
|
52
|
+
reviewNext: {
|
|
53
|
+
helperTool: string;
|
|
54
|
+
listTool: string;
|
|
55
|
+
createTool: string;
|
|
56
|
+
commentTool: string;
|
|
57
|
+
guidance: string;
|
|
58
|
+
};
|
|
59
|
+
reason?: undefined;
|
|
60
|
+
} | {
|
|
61
|
+
available: boolean;
|
|
62
|
+
nextTool: string;
|
|
63
|
+
suggestedArgs: {
|
|
64
|
+
documentId: string;
|
|
65
|
+
};
|
|
66
|
+
guidance: string;
|
|
67
|
+
reviewNext: {
|
|
68
|
+
helperTool: string;
|
|
69
|
+
listTool: string;
|
|
70
|
+
createTool: string;
|
|
71
|
+
commentTool: string;
|
|
72
|
+
guidance: string;
|
|
73
|
+
};
|
|
74
|
+
reason: string;
|
|
75
|
+
};
|
|
76
|
+
buildCanonicalDocumentAttachmentHint: (asset: {
|
|
77
|
+
assetId: string;
|
|
78
|
+
documentId: string | null;
|
|
79
|
+
referenceNumber?: number | null;
|
|
80
|
+
mimeType?: string | null;
|
|
81
|
+
}) => {
|
|
82
|
+
documentId: string | null;
|
|
83
|
+
preferredNextTool: string;
|
|
84
|
+
preferredWorkflow: string;
|
|
85
|
+
suggestedArgs: {
|
|
86
|
+
documentId: string;
|
|
87
|
+
};
|
|
88
|
+
guidance: string;
|
|
89
|
+
} | null;
|
|
90
|
+
searchDocumentAssets: (queryRaw: unknown, options?: {
|
|
91
|
+
limit?: unknown;
|
|
92
|
+
}) => Array<{
|
|
93
|
+
asset: WorkspaceAssetEntry;
|
|
94
|
+
matchedOn: string[];
|
|
95
|
+
score: number;
|
|
96
|
+
}>;
|
|
97
|
+
resolveDocumentAssetByIdentifierOrThrow: (documentIdentifier: unknown, options?: {
|
|
98
|
+
notFoundMessage?: string;
|
|
99
|
+
}) => WorkspaceAssetEntry;
|
|
100
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
export function createDocumentHelpers(deps) {
|
|
2
|
+
const buildDocumentDescriptor = (asset) => ({
|
|
3
|
+
assetId: asset.assetId,
|
|
4
|
+
documentId: asset.documentId ?? null,
|
|
5
|
+
referenceNumber: typeof asset.referenceNumber === 'number' ? asset.referenceNumber : null,
|
|
6
|
+
referenceLabel: deps.getDocumentReferenceLabel(asset),
|
|
7
|
+
logicalName: asset.logicalName ?? null,
|
|
8
|
+
originalFilename: asset.originalFilename ?? null,
|
|
9
|
+
version: typeof asset.version === 'number' ? asset.version : null,
|
|
10
|
+
storageKey: asset.storageKey ?? null,
|
|
11
|
+
mimeType: asset.mimeType ?? null,
|
|
12
|
+
sizeBytes: typeof asset.sizeBytes === 'number' ? asset.sizeBytes : null,
|
|
13
|
+
updatedAt: asset.updatedAt ?? null,
|
|
14
|
+
apiUrl: `/api/taskforce/documents/${encodeURIComponent(String(asset.assetId || '').trim())}/content`,
|
|
15
|
+
});
|
|
16
|
+
const buildDocumentReadHint = (asset) => {
|
|
17
|
+
const preferredIdentifier = deps.getDocumentReferenceLabel(asset)
|
|
18
|
+
|| (typeof asset.documentId === 'string' && asset.documentId.trim().length > 0 ? asset.documentId.trim() : null)
|
|
19
|
+
|| String(asset.assetId || '').trim();
|
|
20
|
+
const readable = deps.isTextReadableMimeType(asset.mimeType || '');
|
|
21
|
+
if (readable) {
|
|
22
|
+
return {
|
|
23
|
+
available: true,
|
|
24
|
+
nextTool: 'read_document_content',
|
|
25
|
+
suggestedArgs: { documentId: preferredIdentifier },
|
|
26
|
+
guidance: 'To read the document body, call read_document_content with this documentId.',
|
|
27
|
+
reviewNext: {
|
|
28
|
+
helperTool: 'review_document',
|
|
29
|
+
listTool: 'get_document_review_sessions',
|
|
30
|
+
createTool: 'create_document_review_session',
|
|
31
|
+
commentTool: 'add_document_review_comment',
|
|
32
|
+
guidance: 'After reading the document body, prefer review_document for a lower-friction review flow, or use get_document_review_sessions/create_document_review_session and add_document_review_comment directly.'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
available: false,
|
|
38
|
+
nextTool: 'read_document_content',
|
|
39
|
+
suggestedArgs: { documentId: preferredIdentifier },
|
|
40
|
+
guidance: 'This document is not inline-readable as text. Call read_document_content to get the structured download/reference response.',
|
|
41
|
+
reviewNext: {
|
|
42
|
+
helperTool: 'review_document',
|
|
43
|
+
listTool: 'get_document_review_sessions',
|
|
44
|
+
createTool: 'create_document_review_session',
|
|
45
|
+
commentTool: 'add_document_review_comment',
|
|
46
|
+
guidance: 'After inspecting the document access response, prefer review_document for a lower-friction review flow, or use get_document_review_sessions/create_document_review_session and add_document_review_comment directly.'
|
|
47
|
+
},
|
|
48
|
+
reason: 'binary_file',
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const buildCanonicalDocumentAttachmentHint = (asset) => {
|
|
52
|
+
const preferredIdentifier = deps.getDocumentReferenceLabel(asset)
|
|
53
|
+
|| (typeof asset.documentId === 'string' && asset.documentId.trim().length > 0 ? asset.documentId.trim() : null)
|
|
54
|
+
|| String(asset.assetId || '').trim();
|
|
55
|
+
if (!preferredIdentifier) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const readable = deps.isTextReadableMimeType(asset.mimeType || '');
|
|
59
|
+
return {
|
|
60
|
+
documentId: typeof asset.documentId === 'string' && asset.documentId.trim().length > 0 ? asset.documentId.trim() : null,
|
|
61
|
+
preferredNextTool: 'get_document',
|
|
62
|
+
preferredWorkflow: 'canonical_document',
|
|
63
|
+
suggestedArgs: { documentId: preferredIdentifier },
|
|
64
|
+
guidance: readable
|
|
65
|
+
? 'This attachment is a canonical document. Prefer get_document, then read_document_content, for ongoing document work and review.'
|
|
66
|
+
: 'This attachment is a canonical document. Prefer get_document for metadata and review context, then read_document_content for the structured content/download response.',
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const searchDocumentAssets = (queryRaw, options) => {
|
|
70
|
+
const query = typeof queryRaw === 'string' ? queryRaw.trim().toLowerCase() : '';
|
|
71
|
+
if (!query) {
|
|
72
|
+
throw new Error('query is required');
|
|
73
|
+
}
|
|
74
|
+
if (!deps.workspaceAssetStore) {
|
|
75
|
+
throw new Error('Workspace asset store unavailable.');
|
|
76
|
+
}
|
|
77
|
+
const requestedLimit = Number(options?.limit);
|
|
78
|
+
const limit = Number.isFinite(requestedLimit)
|
|
79
|
+
? Math.max(1, Math.min(50, Math.trunc(requestedLimit)))
|
|
80
|
+
: 10;
|
|
81
|
+
const normalize = (value) => typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
82
|
+
const tokenize = (value) => normalize(value).split(/[^a-z0-9]+/i).filter(Boolean);
|
|
83
|
+
const allDocuments = deps.workspaceAssetStore.listAllByWorkspace(deps.activeWorkspaceId, { kind: 'document' });
|
|
84
|
+
const scoredMatches = allDocuments.flatMap((asset) => {
|
|
85
|
+
if (asset.deletedAt)
|
|
86
|
+
return [];
|
|
87
|
+
const fields = [
|
|
88
|
+
{ label: 'referenceLabel', value: deps.getDocumentReferenceLabel(asset) || '' },
|
|
89
|
+
{ label: 'documentId', value: asset.documentId || '' },
|
|
90
|
+
{ label: 'logicalName', value: asset.logicalName || '' },
|
|
91
|
+
{ label: 'originalFilename', value: asset.originalFilename || '' },
|
|
92
|
+
{ label: 'assetId', value: asset.assetId || '' },
|
|
93
|
+
];
|
|
94
|
+
let score = 0;
|
|
95
|
+
const matchedOn = new Set();
|
|
96
|
+
for (const field of fields) {
|
|
97
|
+
const normalized = normalize(field.value);
|
|
98
|
+
if (!normalized)
|
|
99
|
+
continue;
|
|
100
|
+
if (normalized === query) {
|
|
101
|
+
score += field.label === 'referenceLabel' || field.label === 'documentId' ? 120 : 90;
|
|
102
|
+
matchedOn.add(field.label);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (normalized.startsWith(query)) {
|
|
106
|
+
score += field.label === 'logicalName' || field.label === 'originalFilename' ? 60 : 50;
|
|
107
|
+
matchedOn.add(field.label);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (normalized.includes(query)) {
|
|
111
|
+
score += 35;
|
|
112
|
+
matchedOn.add(field.label);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (tokenize(field.value).some((token) => token.startsWith(query))) {
|
|
116
|
+
score += 20;
|
|
117
|
+
matchedOn.add(field.label);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (score <= 0)
|
|
121
|
+
return [];
|
|
122
|
+
return [{ asset, matchedOn: Array.from(matchedOn), score }];
|
|
123
|
+
});
|
|
124
|
+
return scoredMatches
|
|
125
|
+
.sort((a, b) => b.score - a.score || String(b.asset.updatedAt || '').localeCompare(String(a.asset.updatedAt || '')))
|
|
126
|
+
.slice(0, limit);
|
|
127
|
+
};
|
|
128
|
+
const resolveDocumentAssetByIdentifierOrThrow = (documentIdentifier, options) => {
|
|
129
|
+
const normalizedValue = typeof documentIdentifier === 'string' ? documentIdentifier.trim() : '';
|
|
130
|
+
if (!normalizedValue) {
|
|
131
|
+
throw new Error('documentId is required');
|
|
132
|
+
}
|
|
133
|
+
if (!deps.workspaceAssetStore) {
|
|
134
|
+
throw new Error('Workspace asset store unavailable.');
|
|
135
|
+
}
|
|
136
|
+
const matchesDocumentAsset = (asset) => Boolean(asset && asset.kind === 'document' && asset.deletedAt == null);
|
|
137
|
+
const directAsset = deps.workspaceAssetStore.get(normalizedValue, deps.activeWorkspaceId);
|
|
138
|
+
if (matchesDocumentAsset(directAsset)) {
|
|
139
|
+
return directAsset;
|
|
140
|
+
}
|
|
141
|
+
const documentAssets = deps.workspaceAssetStore.listAllByWorkspace(deps.activeWorkspaceId, { kind: 'document' });
|
|
142
|
+
const referenceNumber = deps.parseDocumentReference(normalizedValue);
|
|
143
|
+
const matchedAsset = documentAssets.find((asset) => asset.documentId === normalizedValue)
|
|
144
|
+
|| (referenceNumber
|
|
145
|
+
? documentAssets.find((asset) => asset.referenceNumber === referenceNumber && asset.isLatest)
|
|
146
|
+
|| documentAssets.find((asset) => asset.referenceNumber === referenceNumber)
|
|
147
|
+
: null);
|
|
148
|
+
if (matchesDocumentAsset(matchedAsset)) {
|
|
149
|
+
return matchedAsset;
|
|
150
|
+
}
|
|
151
|
+
throw new Error(options?.notFoundMessage
|
|
152
|
+
|| `Document ${normalizedValue} not found in workspace ${deps.activeWorkspaceId}. If you only know a keyword, filename, or rough title, call search_documents first.`);
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
buildDocumentDescriptor,
|
|
156
|
+
buildDocumentReadHint,
|
|
157
|
+
buildCanonicalDocumentAttachmentHint,
|
|
158
|
+
searchDocumentAssets,
|
|
159
|
+
resolveDocumentAssetByIdentifierOrThrow,
|
|
160
|
+
};
|
|
161
|
+
}
|