@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 @@
|
|
|
1
|
+
export {};
|
|
@@ -25,6 +25,7 @@ export declare function pullWorkspaceChanges(resolveCloudAuthUrl: (path: string)
|
|
|
25
25
|
nextCursor?: string | null;
|
|
26
26
|
hasMore?: boolean;
|
|
27
27
|
workspaceMembers?: WorkspaceSyncWorkspaceMemberSnapshot[];
|
|
28
|
+
diagnostics?: Record<string, unknown>;
|
|
28
29
|
}>>;
|
|
29
30
|
export declare function pushWorkspaceChanges(resolveCloudAuthUrl: (path: string) => string, input: {
|
|
30
31
|
workspaceId: string;
|
|
@@ -39,6 +39,10 @@ export function normalizeAiProfileSyncPayload(raw, workspaceId, normalizeSurface
|
|
|
39
39
|
username: String(profile.username || '').trim(),
|
|
40
40
|
icon: String(profile.icon || 'Bot').trim() || 'Bot',
|
|
41
41
|
color: String(profile.color || '#8b5cf6').trim() || '#8b5cf6',
|
|
42
|
+
description: toNullableTrimmedString(profile.description),
|
|
43
|
+
role: toNullableTrimmedString(profile.role),
|
|
44
|
+
provider: toNullableTrimmedString(profile.provider),
|
|
45
|
+
model: toNullableTrimmedString(profile.model),
|
|
42
46
|
surfaceType: normalizeSurfaceType(profile.surfaceType, { source, profileId, workspaceId: profileWorkspaceId }),
|
|
43
47
|
providerMetadata: profile.providerMetadata && typeof profile.providerMetadata === 'object' && !Array.isArray(profile.providerMetadata)
|
|
44
48
|
? profile.providerMetadata
|
|
@@ -15,6 +15,10 @@ describe('collaborationSyncPayload', () => {
|
|
|
15
15
|
username: ' agent ',
|
|
16
16
|
icon: ' Bot ',
|
|
17
17
|
color: ' #111111 ',
|
|
18
|
+
description: ' Product coding agent ',
|
|
19
|
+
role: ' Implementer ',
|
|
20
|
+
provider: ' OpenAI ',
|
|
21
|
+
model: ' gpt-5.4 ',
|
|
18
22
|
surfaceType: 'agent',
|
|
19
23
|
providerMetadata: { foo: 'bar' },
|
|
20
24
|
createdAt: '2026-04-10T10:00:00.000Z',
|
|
@@ -29,6 +33,10 @@ describe('collaborationSyncPayload', () => {
|
|
|
29
33
|
username: 'agent',
|
|
30
34
|
icon: 'Bot',
|
|
31
35
|
color: '#111111',
|
|
36
|
+
description: 'Product coding agent',
|
|
37
|
+
role: 'Implementer',
|
|
38
|
+
provider: 'OpenAI',
|
|
39
|
+
model: 'gpt-5.4',
|
|
32
40
|
surfaceType: 'agent',
|
|
33
41
|
providerMetadata: { foo: 'bar' },
|
|
34
42
|
createdAt: '2026-04-10T10:00:00.000Z',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
|
|
2
|
-
import type { WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot } from './workspaceSyncModel.js';
|
|
2
|
+
import type { WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncTaskEventSnapshot } from './workspaceSyncModel.js';
|
|
3
3
|
type SyncCore = TaskforceCore & TaskforceSyncCapable;
|
|
4
4
|
interface CollaborationSyncStateDeps {
|
|
5
5
|
core: SyncCore;
|
|
@@ -7,9 +7,11 @@ interface CollaborationSyncStateDeps {
|
|
|
7
7
|
export declare function listWorkspaceSyncDocumentReviewSessionsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncDocumentReviewSessionSnapshot[];
|
|
8
8
|
export declare function listWorkspaceSyncDocumentReviewCommentsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncDocumentReviewCommentSnapshot[];
|
|
9
9
|
export declare function listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncAnnotatedAttachmentSessionSnapshot[];
|
|
10
|
+
export declare function listWorkspaceSyncTaskEventsSnapshot(deps: CollaborationSyncStateDeps, workspaceId?: string): WorkspaceSyncTaskEventSnapshot[];
|
|
10
11
|
export declare function createCollaborationSyncState(deps: CollaborationSyncStateDeps): {
|
|
11
12
|
listWorkspaceSyncDocumentReviewSessionsSnapshot: (workspaceId?: string) => WorkspaceSyncDocumentReviewSessionSnapshot[];
|
|
12
13
|
listWorkspaceSyncDocumentReviewCommentsSnapshot: (workspaceId?: string) => WorkspaceSyncDocumentReviewCommentSnapshot[];
|
|
13
14
|
listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot: (workspaceId?: string) => WorkspaceSyncAnnotatedAttachmentSessionSnapshot[];
|
|
15
|
+
listWorkspaceSyncTaskEventsSnapshot: (workspaceId?: string) => WorkspaceSyncTaskEventSnapshot[];
|
|
14
16
|
};
|
|
15
17
|
export {};
|
|
@@ -51,10 +51,29 @@ export function listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(deps, works
|
|
|
51
51
|
&& session.workspaceId.length > 0
|
|
52
52
|
&& session.baseImageAssetId.length > 0));
|
|
53
53
|
}
|
|
54
|
+
export function listWorkspaceSyncTaskEventsSnapshot(deps, workspaceId = 'default') {
|
|
55
|
+
return deps.core.listTaskEventsForSync({ workspaceId })
|
|
56
|
+
.map((event) => ({
|
|
57
|
+
id: event.id,
|
|
58
|
+
taskId: event.taskId,
|
|
59
|
+
workspaceId: event.workspaceId,
|
|
60
|
+
action: event.action,
|
|
61
|
+
actor: event.actor,
|
|
62
|
+
actorType: event.actorType,
|
|
63
|
+
details: event.details,
|
|
64
|
+
createdAt: event.createdAt,
|
|
65
|
+
}))
|
|
66
|
+
.filter((event) => (event.id.length > 0
|
|
67
|
+
&& event.taskId.length > 0
|
|
68
|
+
&& event.workspaceId.length > 0
|
|
69
|
+
&& event.action.length > 0
|
|
70
|
+
&& event.createdAt.length > 0));
|
|
71
|
+
}
|
|
54
72
|
export function createCollaborationSyncState(deps) {
|
|
55
73
|
return {
|
|
56
74
|
listWorkspaceSyncDocumentReviewSessionsSnapshot: (workspaceId = 'default') => listWorkspaceSyncDocumentReviewSessionsSnapshot(deps, workspaceId),
|
|
57
75
|
listWorkspaceSyncDocumentReviewCommentsSnapshot: (workspaceId = 'default') => listWorkspaceSyncDocumentReviewCommentsSnapshot(deps, workspaceId),
|
|
58
76
|
listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot: (workspaceId = 'default') => listWorkspaceSyncAnnotatedAttachmentSessionsSnapshot(deps, workspaceId),
|
|
77
|
+
listWorkspaceSyncTaskEventsSnapshot: (workspaceId = 'default') => listWorkspaceSyncTaskEventsSnapshot(deps, workspaceId),
|
|
59
78
|
};
|
|
60
79
|
}
|
|
@@ -21,6 +21,8 @@ interface ContentSyncStateDeps {
|
|
|
21
21
|
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
22
22
|
workspaceDocumentSnapshotCache: Map<string, Map<string, CachedWorkspaceSyncDocument>>;
|
|
23
23
|
}
|
|
24
|
+
export type DocumentSyncIndexEntry = Omit<DocumentSyncPayload, 'content'>;
|
|
25
|
+
export type BinaryAssetSyncIndexEntry = Omit<BinaryAssetSyncPayload, 'contentBase64'>;
|
|
24
26
|
export declare function resolveCanonicalAssetSyncLinkState(deps: ContentSyncStateDeps, asset: WorkspaceAssetEntry, workspaceId: string): {
|
|
25
27
|
primaryLink: WorkspaceAssetLinkEntry | null;
|
|
26
28
|
effectiveUpdatedAt: string;
|
|
@@ -42,7 +44,11 @@ export declare function reconcileWorkspaceSyncLinks(deps: ContentSyncStateDeps,
|
|
|
42
44
|
}): void;
|
|
43
45
|
export declare function listWorkspaceSyncDocumentDeletesSnapshot(deps: ContentSyncStateDeps, workspaceId?: string): DocumentDeleteSyncPayload[];
|
|
44
46
|
export declare function listWorkspaceSyncDocumentsSnapshot(deps: ContentSyncStateDeps, basePath: string, workspaceId?: string): Promise<DocumentSyncPayload[]>;
|
|
47
|
+
export declare function listWorkspaceSyncDocumentIndex(deps: ContentSyncStateDeps, basePath: string, workspaceId?: string): Promise<DocumentSyncIndexEntry[]>;
|
|
45
48
|
export declare function listWorkspaceSyncBinaryAssetsSnapshot(deps: ContentSyncStateDeps, basePath: string, workspaceId?: string): Promise<BinaryAssetSyncPayload[]>;
|
|
49
|
+
export declare function listWorkspaceSyncBinaryAssetIndex(deps: ContentSyncStateDeps, workspaceId?: string): Promise<BinaryAssetSyncIndexEntry[]>;
|
|
50
|
+
export declare function loadWorkspaceSyncDocumentPayload(deps: ContentSyncStateDeps, basePath: string, workspaceId: string, relativePath: string): Promise<DocumentSyncPayload | null>;
|
|
51
|
+
export declare function loadWorkspaceSyncBinaryAssetPayload(deps: ContentSyncStateDeps, basePath: string, workspaceId: string, assetPath: string): Promise<BinaryAssetSyncPayload | null>;
|
|
46
52
|
export declare function listWorkspaceSyncBinaryAssetDeletesSnapshot(deps: ContentSyncStateDeps, workspaceId?: string): BinaryAssetDeleteSyncPayload[];
|
|
47
53
|
export declare function writeWorkspaceSyncDocument(deps: ContentSyncStateDeps, basePath: string, doc: DocumentSyncPayload, workspaceId?: string, options?: {
|
|
48
54
|
allowReferenceNumberReassignment?: boolean;
|
|
@@ -73,8 +79,12 @@ export declare function createContentSyncState(deps: ContentSyncStateDeps): {
|
|
|
73
79
|
updatedAt?: string | null;
|
|
74
80
|
}) => void;
|
|
75
81
|
listWorkspaceSyncDocumentDeletesSnapshot: (workspaceId?: string) => DocumentDeleteSyncPayload[];
|
|
82
|
+
listWorkspaceSyncDocumentIndex: (basePath: string, workspaceId?: string) => Promise<DocumentSyncIndexEntry[]>;
|
|
76
83
|
listWorkspaceSyncDocumentsSnapshot: (basePath: string, workspaceId?: string) => Promise<DocumentSyncPayload[]>;
|
|
84
|
+
loadWorkspaceSyncDocumentPayload: (basePath: string, workspaceId: string, relativePath: string) => Promise<DocumentSyncPayload | null>;
|
|
85
|
+
listWorkspaceSyncBinaryAssetIndex: (workspaceId?: string) => Promise<BinaryAssetSyncIndexEntry[]>;
|
|
77
86
|
listWorkspaceSyncBinaryAssetsSnapshot: (basePath: string, workspaceId?: string) => Promise<BinaryAssetSyncPayload[]>;
|
|
87
|
+
loadWorkspaceSyncBinaryAssetPayload: (basePath: string, workspaceId: string, assetPath: string) => Promise<BinaryAssetSyncPayload | null>;
|
|
78
88
|
listWorkspaceSyncBinaryAssetDeletesSnapshot: (workspaceId?: string) => BinaryAssetDeleteSyncPayload[];
|
|
79
89
|
writeWorkspaceSyncDocument: (basePath: string, doc: DocumentSyncPayload, workspaceId?: string, options?: {
|
|
80
90
|
allowReferenceNumberReassignment?: boolean;
|
|
@@ -68,10 +68,10 @@ export function hasDocumentSyncMetadataDrift(deps, workspaceId, doc, options) {
|
|
|
68
68
|
: null;
|
|
69
69
|
const normalizedIncomingLinkRole = doc.linkRole === 'reference' ? 'reference' : 'attachment';
|
|
70
70
|
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
71
|
-
|
|
72
|
-
&& existingAsset.referenceNumber
|
|
71
|
+
const referenceNumberMismatch = Boolean(existingAsset.referenceNumber
|
|
73
72
|
&& normalizedIncomingReference
|
|
74
|
-
&& existingAsset.referenceNumber !== normalizedIncomingReference)
|
|
73
|
+
&& existingAsset.referenceNumber !== normalizedIncomingReference);
|
|
74
|
+
if (referenceNumberMismatch) {
|
|
75
75
|
deps.recordSyncDiagnostic(workspaceId, 'apply', 'Detected document reference number mismatch during normal sync.', {
|
|
76
76
|
source: 'documents.referenceNumber.mismatch',
|
|
77
77
|
path: doc.path,
|
|
@@ -117,10 +117,10 @@ export function hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset, option
|
|
|
117
117
|
? 'image'
|
|
118
118
|
: 'attachment';
|
|
119
119
|
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
120
|
-
|
|
121
|
-
&& existingAsset.referenceNumber
|
|
120
|
+
const referenceNumberMismatch = Boolean(existingAsset.referenceNumber
|
|
122
121
|
&& normalizedIncomingReference
|
|
123
|
-
&& existingAsset.referenceNumber !== normalizedIncomingReference)
|
|
122
|
+
&& existingAsset.referenceNumber !== normalizedIncomingReference);
|
|
123
|
+
if (referenceNumberMismatch) {
|
|
124
124
|
deps.recordSyncDiagnostic(workspaceId, 'apply', 'Detected asset reference number mismatch during normal sync.', {
|
|
125
125
|
source: 'assets.referenceNumber.mismatch',
|
|
126
126
|
path: asset.path,
|
|
@@ -344,6 +344,80 @@ export async function listWorkspaceSyncDocumentsSnapshot(deps, basePath, workspa
|
|
|
344
344
|
}
|
|
345
345
|
return docs;
|
|
346
346
|
}
|
|
347
|
+
export async function listWorkspaceSyncDocumentIndex(deps, basePath, workspaceId = 'default') {
|
|
348
|
+
const root = path.resolve(basePath);
|
|
349
|
+
const candidatePaths = new Set();
|
|
350
|
+
const docsRoot = path.join(root, 'docs');
|
|
351
|
+
const collectMarkdownPaths = (directory) => {
|
|
352
|
+
if (!fs.existsSync(directory))
|
|
353
|
+
return;
|
|
354
|
+
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
355
|
+
for (const entry of entries) {
|
|
356
|
+
const absolutePath = path.join(directory, entry.name);
|
|
357
|
+
if (entry.isDirectory()) {
|
|
358
|
+
collectMarkdownPaths(absolutePath);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (!entry.isFile())
|
|
362
|
+
continue;
|
|
363
|
+
const relativeFromRoot = path.relative(root, absolutePath).replace(/\\/g, '/');
|
|
364
|
+
const normalized = deps.normalizeWorkspaceSyncDocumentPath(relativeFromRoot);
|
|
365
|
+
if (normalized)
|
|
366
|
+
candidatePaths.add(normalized);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
collectMarkdownPaths(docsRoot);
|
|
370
|
+
if (deps.workspaceAssetStore) {
|
|
371
|
+
const canonicalAssets = deps.workspaceAssetStore.listAllByWorkspace(workspaceId, {
|
|
372
|
+
includeDeleted: false,
|
|
373
|
+
kind: 'document'
|
|
374
|
+
});
|
|
375
|
+
for (const asset of canonicalAssets) {
|
|
376
|
+
const normalized = deps.normalizeWorkspaceSyncDocumentPath(asset.storageKey);
|
|
377
|
+
if (normalized)
|
|
378
|
+
candidatePaths.add(normalized);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const docs = [];
|
|
382
|
+
for (const relativePath of Array.from(candidatePaths).sort((a, b) => a.localeCompare(b))) {
|
|
383
|
+
try {
|
|
384
|
+
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(relativePath, workspaceId);
|
|
385
|
+
let updatedAt = '';
|
|
386
|
+
if (canonicalAsset?.kind === 'document') {
|
|
387
|
+
updatedAt = resolveCanonicalAssetSyncLinkState(deps, canonicalAsset, workspaceId).effectiveUpdatedAt;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
const absPath = path.resolve(path.join(basePath, relativePath));
|
|
391
|
+
const safeRoot = path.resolve(basePath);
|
|
392
|
+
if (absPath !== safeRoot && !absPath.startsWith(`${safeRoot}${path.sep}`))
|
|
393
|
+
continue;
|
|
394
|
+
if (!fs.existsSync(absPath))
|
|
395
|
+
continue;
|
|
396
|
+
const stat = fs.statSync(absPath);
|
|
397
|
+
if (!stat.isFile())
|
|
398
|
+
continue;
|
|
399
|
+
const existing = deps.core.getDocumentWatermark(workspaceId, relativePath);
|
|
400
|
+
updatedAt = existing?.updatedAt
|
|
401
|
+
|| (Number.isFinite(stat.mtimeMs) ? new Date(stat.mtimeMs).toISOString() : new Date().toISOString());
|
|
402
|
+
}
|
|
403
|
+
if (!Number.isFinite(Date.parse(String(updatedAt || '').trim())))
|
|
404
|
+
continue;
|
|
405
|
+
docs.push({
|
|
406
|
+
path: relativePath,
|
|
407
|
+
updatedAt: String(updatedAt || '').trim(),
|
|
408
|
+
...getCanonicalSyncDocumentMetadata(deps, relativePath, workspaceId)
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to index sync document snapshot entry.', {
|
|
413
|
+
source: 'documents.snapshot.indexEntry',
|
|
414
|
+
path: relativePath,
|
|
415
|
+
error: String(error?.message || error || '')
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return docs;
|
|
420
|
+
}
|
|
347
421
|
export async function listWorkspaceSyncBinaryAssetsSnapshot(deps, basePath, workspaceId = 'default') {
|
|
348
422
|
if (!deps.workspaceAssetStore)
|
|
349
423
|
return [];
|
|
@@ -418,6 +492,181 @@ export async function listWorkspaceSyncBinaryAssetsSnapshot(deps, basePath, work
|
|
|
418
492
|
}
|
|
419
493
|
return snapshots;
|
|
420
494
|
}
|
|
495
|
+
export async function listWorkspaceSyncBinaryAssetIndex(deps, workspaceId = 'default') {
|
|
496
|
+
if (!deps.workspaceAssetStore)
|
|
497
|
+
return [];
|
|
498
|
+
const assets = deps.workspaceAssetStore.listAllByWorkspace(workspaceId, {
|
|
499
|
+
includeDeleted: false
|
|
500
|
+
});
|
|
501
|
+
return assets
|
|
502
|
+
.filter((asset) => asset.kind === 'image' || asset.kind === 'file')
|
|
503
|
+
.filter((asset) => asset.storageProvider !== 'external')
|
|
504
|
+
.filter((asset) => {
|
|
505
|
+
const storageKey = String(asset.storageKey || '').trim();
|
|
506
|
+
return Boolean(storageKey && deps.normalizeTaskDataRelativePath(storageKey));
|
|
507
|
+
})
|
|
508
|
+
.map((asset) => {
|
|
509
|
+
const storageKey = String(asset.storageKey || '').trim();
|
|
510
|
+
const { primaryLink, effectiveUpdatedAt } = resolveCanonicalAssetSyncLinkState(deps, asset, workspaceId);
|
|
511
|
+
const assetKind = asset.kind === 'image' ? 'image' : 'file';
|
|
512
|
+
return {
|
|
513
|
+
path: storageKey,
|
|
514
|
+
updatedAt: effectiveUpdatedAt,
|
|
515
|
+
assetId: asset.assetId,
|
|
516
|
+
kind: assetKind,
|
|
517
|
+
mimeType: asset.mimeType || 'application/octet-stream',
|
|
518
|
+
referenceNumber: asset.referenceNumber,
|
|
519
|
+
taskId: primaryLink?.taskId || null,
|
|
520
|
+
logicalName: asset.logicalName || null,
|
|
521
|
+
caption: primaryLink?.displayName || null,
|
|
522
|
+
originalFilename: asset.originalFilename || path.basename(storageKey),
|
|
523
|
+
linkRole: primaryLink?.role || (asset.kind === 'image' ? 'image' : 'attachment')
|
|
524
|
+
};
|
|
525
|
+
})
|
|
526
|
+
.filter((entry) => Number.isFinite(Date.parse(entry.updatedAt)) && entry.path.length > 0);
|
|
527
|
+
}
|
|
528
|
+
export async function loadWorkspaceSyncDocumentPayload(deps, basePath, workspaceId, relativePath) {
|
|
529
|
+
const normalizedPath = deps.normalizeWorkspaceSyncDocumentPath(relativePath);
|
|
530
|
+
if (!normalizedPath)
|
|
531
|
+
return null;
|
|
532
|
+
const root = path.resolve(basePath);
|
|
533
|
+
const absolutePath = path.resolve(path.join(root, normalizedPath));
|
|
534
|
+
if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`))
|
|
535
|
+
return null;
|
|
536
|
+
let content = '';
|
|
537
|
+
let stat = null;
|
|
538
|
+
try {
|
|
539
|
+
if (!fs.existsSync(absolutePath))
|
|
540
|
+
return null;
|
|
541
|
+
stat = fs.statSync(absolutePath);
|
|
542
|
+
if (!stat.isFile())
|
|
543
|
+
return null;
|
|
544
|
+
content = fs.readFileSync(absolutePath, 'utf8');
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to load targeted sync document payload.', {
|
|
548
|
+
source: 'documents.snapshot.loadPayload',
|
|
549
|
+
path: normalizedPath,
|
|
550
|
+
error: String(error?.message || error || '')
|
|
551
|
+
});
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
const workspaceCache = deps.workspaceDocumentSnapshotCache.get(workspaceId)
|
|
555
|
+
?? (() => {
|
|
556
|
+
const next = new Map();
|
|
557
|
+
deps.workspaceDocumentSnapshotCache.set(workspaceId, next);
|
|
558
|
+
return next;
|
|
559
|
+
})();
|
|
560
|
+
const cached = workspaceCache.get(normalizedPath);
|
|
561
|
+
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(normalizedPath, workspaceId);
|
|
562
|
+
let updatedAt = '';
|
|
563
|
+
if (canonicalAsset?.kind === 'document') {
|
|
564
|
+
updatedAt = resolveCanonicalAssetSyncLinkState(deps, canonicalAsset, workspaceId).effectiveUpdatedAt;
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
const contentHash = createHash('sha256').update(content).digest('hex');
|
|
568
|
+
const existing = deps.core.getDocumentWatermark(workspaceId, normalizedPath);
|
|
569
|
+
if (existing && existing.contentHash === contentHash) {
|
|
570
|
+
updatedAt = existing.updatedAt;
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
updatedAt = stat && Number.isFinite(stat.mtimeMs)
|
|
574
|
+
? new Date(stat.mtimeMs).toISOString()
|
|
575
|
+
: new Date().toISOString();
|
|
576
|
+
try {
|
|
577
|
+
deps.core.upsertDocumentWatermark(workspaceId, normalizedPath, contentHash, updatedAt);
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to persist document watermark during targeted payload load.', {
|
|
581
|
+
source: 'documents.snapshot.loadPayload.upsertWatermark',
|
|
582
|
+
path: normalizedPath,
|
|
583
|
+
error: String(error?.message || error || '')
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (cached
|
|
589
|
+
&& stat
|
|
590
|
+
&& cached.size === Buffer.byteLength(content, 'utf8')
|
|
591
|
+
&& (canonicalAsset
|
|
592
|
+
? cached.updatedAt === updatedAt
|
|
593
|
+
: cached.mtimeMs === stat.mtimeMs && cached.ctimeMs === stat.ctimeMs)) {
|
|
594
|
+
return {
|
|
595
|
+
path: normalizedPath,
|
|
596
|
+
updatedAt: cached.updatedAt,
|
|
597
|
+
content: cached.content,
|
|
598
|
+
...getCanonicalSyncDocumentMetadata(deps, normalizedPath, workspaceId)
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
workspaceCache.set(normalizedPath, {
|
|
602
|
+
path: normalizedPath,
|
|
603
|
+
mtimeMs: stat?.mtimeMs ?? 0,
|
|
604
|
+
ctimeMs: stat?.ctimeMs ?? 0,
|
|
605
|
+
size: Buffer.byteLength(content, 'utf8'),
|
|
606
|
+
updatedAt,
|
|
607
|
+
content
|
|
608
|
+
});
|
|
609
|
+
return {
|
|
610
|
+
path: normalizedPath,
|
|
611
|
+
updatedAt,
|
|
612
|
+
content,
|
|
613
|
+
...getCanonicalSyncDocumentMetadata(deps, normalizedPath, workspaceId)
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
export async function loadWorkspaceSyncBinaryAssetPayload(deps, basePath, workspaceId, assetPath) {
|
|
617
|
+
const normalizedPath = deps.normalizeTaskDataRelativePath(assetPath);
|
|
618
|
+
if (!normalizedPath)
|
|
619
|
+
return null;
|
|
620
|
+
if (!deps.workspaceAssetStore)
|
|
621
|
+
return null;
|
|
622
|
+
const asset = deps.workspaceAssetStore.getByStorageKey(normalizedPath, workspaceId);
|
|
623
|
+
if (!asset || (asset.kind !== 'image' && asset.kind !== 'file') || asset.storageProvider === 'external') {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
const objectStorageClient = deps.getObjectStorageClient();
|
|
627
|
+
let buffer = null;
|
|
628
|
+
try {
|
|
629
|
+
if (asset.storageProvider === 'r2' && objectStorageClient) {
|
|
630
|
+
const object = await objectStorageClient.getObject(normalizedPath);
|
|
631
|
+
buffer = object?.body || null;
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
const root = path.resolve(basePath);
|
|
635
|
+
const absolutePath = path.resolve(root, normalizedPath);
|
|
636
|
+
if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`))
|
|
637
|
+
return null;
|
|
638
|
+
if (!fs.existsSync(absolutePath))
|
|
639
|
+
return null;
|
|
640
|
+
buffer = fs.readFileSync(absolutePath);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
catch (error) {
|
|
644
|
+
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to load targeted binary asset payload.', {
|
|
645
|
+
source: 'assets.snapshot.loadPayload',
|
|
646
|
+
path: normalizedPath,
|
|
647
|
+
assetId: asset.assetId,
|
|
648
|
+
error: String(error?.message || error || '')
|
|
649
|
+
});
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
if (!buffer)
|
|
653
|
+
return null;
|
|
654
|
+
const { primaryLink, effectiveUpdatedAt } = resolveCanonicalAssetSyncLinkState(deps, asset, workspaceId);
|
|
655
|
+
return {
|
|
656
|
+
path: normalizedPath,
|
|
657
|
+
updatedAt: effectiveUpdatedAt,
|
|
658
|
+
contentBase64: buffer.toString('base64'),
|
|
659
|
+
assetId: asset.assetId,
|
|
660
|
+
kind: asset.kind,
|
|
661
|
+
mimeType: asset.mimeType || 'application/octet-stream',
|
|
662
|
+
referenceNumber: asset.referenceNumber,
|
|
663
|
+
taskId: primaryLink?.taskId || null,
|
|
664
|
+
logicalName: asset.logicalName || null,
|
|
665
|
+
caption: primaryLink?.displayName || null,
|
|
666
|
+
originalFilename: asset.originalFilename || path.basename(normalizedPath),
|
|
667
|
+
linkRole: primaryLink?.role || (asset.kind === 'image' ? 'image' : 'attachment')
|
|
668
|
+
};
|
|
669
|
+
}
|
|
421
670
|
export function listWorkspaceSyncBinaryAssetDeletesSnapshot(deps, workspaceId = 'default') {
|
|
422
671
|
if (!deps.workspaceAssetStore)
|
|
423
672
|
return [];
|
|
@@ -479,6 +728,13 @@ export async function writeWorkspaceSyncDocument(deps, basePath, doc, workspaceI
|
|
|
479
728
|
if (deps.workspaceAssetStore) {
|
|
480
729
|
const existing = deps.workspaceAssetStore.getByStorageKey(normalizedPath, workspaceId);
|
|
481
730
|
const effectiveUpdatedAt = updatedAt || new Date().toISOString();
|
|
731
|
+
const incomingReferenceNumber = Number.isFinite(Number(doc.referenceNumber))
|
|
732
|
+
? Math.max(1, Math.floor(Number(doc.referenceNumber)))
|
|
733
|
+
: null;
|
|
734
|
+
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
735
|
+
const nextReferenceNumber = allowReferenceNumberReassignment
|
|
736
|
+
? (incomingReferenceNumber ?? existing?.referenceNumber ?? null)
|
|
737
|
+
: (existing?.referenceNumber ?? incomingReferenceNumber ?? null);
|
|
482
738
|
const originalFilename = String(doc.originalFilename || existing?.originalFilename || path.basename(normalizedPath) || 'document.md').trim() || 'document.md';
|
|
483
739
|
const asset = deps.workspaceAssetStore.upsertAsset({
|
|
484
740
|
assetId: String(doc.assetId || existing?.assetId || `asset-${randomUUID().replace(/-/g, '')}`),
|
|
@@ -494,9 +750,7 @@ export async function writeWorkspaceSyncDocument(deps, basePath, doc, workspaceI
|
|
|
494
750
|
contentSha256: contentHash,
|
|
495
751
|
sizeBytes: Buffer.byteLength(content, 'utf8'),
|
|
496
752
|
documentId: String(doc.documentId || existing?.documentId || `doc-${randomUUID().replace(/-/g, '')}`),
|
|
497
|
-
referenceNumber:
|
|
498
|
-
? Math.max(1, Math.floor(Number(doc.referenceNumber)))
|
|
499
|
-
: existing?.referenceNumber || null,
|
|
753
|
+
referenceNumber: nextReferenceNumber,
|
|
500
754
|
version: Number.isFinite(Number(doc.version))
|
|
501
755
|
? Math.max(1, Math.floor(Number(doc.version)))
|
|
502
756
|
: Math.max(1, Number(existing?.version || 0) + 1),
|
|
@@ -509,7 +763,7 @@ export async function writeWorkspaceSyncDocument(deps, basePath, doc, workspaceI
|
|
|
509
763
|
updatedAt: effectiveUpdatedAt,
|
|
510
764
|
deletedAt: null,
|
|
511
765
|
purgeAfter: null,
|
|
512
|
-
allowReferenceNumberReassignment
|
|
766
|
+
allowReferenceNumberReassignment
|
|
513
767
|
});
|
|
514
768
|
const taskId = String(doc.taskId || '').trim();
|
|
515
769
|
reconcileWorkspaceSyncLinks(deps, {
|
|
@@ -569,6 +823,13 @@ export async function writeWorkspaceSyncBinaryAsset(deps, basePath, asset, works
|
|
|
569
823
|
try {
|
|
570
824
|
const existing = deps.workspaceAssetStore.getByStorageKey(normalizedPath, workspaceId);
|
|
571
825
|
const effectiveUpdatedAt = updatedAt || new Date().toISOString();
|
|
826
|
+
const incomingReferenceNumber = Number.isFinite(Number(asset.referenceNumber))
|
|
827
|
+
? Math.max(1, Math.floor(Number(asset.referenceNumber)))
|
|
828
|
+
: null;
|
|
829
|
+
const allowReferenceNumberReassignment = options?.allowReferenceNumberReassignment === true;
|
|
830
|
+
const nextReferenceNumber = allowReferenceNumberReassignment
|
|
831
|
+
? (incomingReferenceNumber ?? existing?.referenceNumber ?? null)
|
|
832
|
+
: (existing?.referenceNumber ?? incomingReferenceNumber ?? null);
|
|
572
833
|
const assetRecord = deps.workspaceAssetStore.upsertAsset({
|
|
573
834
|
assetId: String(asset.assetId || existing?.assetId || `asset-${randomUUID().replace(/-/g, '')}`),
|
|
574
835
|
workspaceId,
|
|
@@ -583,9 +844,7 @@ export async function writeWorkspaceSyncBinaryAsset(deps, basePath, asset, works
|
|
|
583
844
|
contentSha256: createHash('sha256').update(buffer).digest('hex'),
|
|
584
845
|
sizeBytes: buffer.length,
|
|
585
846
|
documentId: null,
|
|
586
|
-
referenceNumber:
|
|
587
|
-
? Math.max(1, Math.floor(Number(asset.referenceNumber)))
|
|
588
|
-
: existing?.referenceNumber || null,
|
|
847
|
+
referenceNumber: nextReferenceNumber,
|
|
589
848
|
version: null,
|
|
590
849
|
isLatest: true,
|
|
591
850
|
scanStatus: existing?.scanStatus || 'clean',
|
|
@@ -596,7 +855,7 @@ export async function writeWorkspaceSyncBinaryAsset(deps, basePath, asset, works
|
|
|
596
855
|
updatedAt: effectiveUpdatedAt,
|
|
597
856
|
deletedAt: null,
|
|
598
857
|
purgeAfter: null,
|
|
599
|
-
allowReferenceNumberReassignment
|
|
858
|
+
allowReferenceNumberReassignment
|
|
600
859
|
});
|
|
601
860
|
const taskId = String(asset.taskId || '').trim();
|
|
602
861
|
reconcileWorkspaceSyncLinks(deps, {
|
|
@@ -732,8 +991,12 @@ export function createContentSyncState(deps) {
|
|
|
732
991
|
hasBinaryAssetSyncMetadataDrift: (workspaceId, asset, options) => hasBinaryAssetSyncMetadataDrift(deps, workspaceId, asset, options),
|
|
733
992
|
reconcileWorkspaceSyncLinks: (input) => reconcileWorkspaceSyncLinks(deps, input),
|
|
734
993
|
listWorkspaceSyncDocumentDeletesSnapshot: (workspaceId = 'default') => listWorkspaceSyncDocumentDeletesSnapshot(deps, workspaceId),
|
|
994
|
+
listWorkspaceSyncDocumentIndex: (basePath, workspaceId = 'default') => listWorkspaceSyncDocumentIndex(deps, basePath, workspaceId),
|
|
735
995
|
listWorkspaceSyncDocumentsSnapshot: (basePath, workspaceId = 'default') => listWorkspaceSyncDocumentsSnapshot(deps, basePath, workspaceId),
|
|
996
|
+
loadWorkspaceSyncDocumentPayload: (basePath, workspaceId, relativePath) => loadWorkspaceSyncDocumentPayload(deps, basePath, workspaceId, relativePath),
|
|
997
|
+
listWorkspaceSyncBinaryAssetIndex: (workspaceId = 'default') => listWorkspaceSyncBinaryAssetIndex(deps, workspaceId),
|
|
736
998
|
listWorkspaceSyncBinaryAssetsSnapshot: (basePath, workspaceId = 'default') => listWorkspaceSyncBinaryAssetsSnapshot(deps, basePath, workspaceId),
|
|
999
|
+
loadWorkspaceSyncBinaryAssetPayload: (basePath, workspaceId, assetPath) => loadWorkspaceSyncBinaryAssetPayload(deps, basePath, workspaceId, assetPath),
|
|
737
1000
|
listWorkspaceSyncBinaryAssetDeletesSnapshot: (workspaceId = 'default') => listWorkspaceSyncBinaryAssetDeletesSnapshot(deps, workspaceId),
|
|
738
1001
|
writeWorkspaceSyncDocument: (basePath, doc, workspaceId = 'default', options) => writeWorkspaceSyncDocument(deps, basePath, doc, workspaceId, options),
|
|
739
1002
|
writeWorkspaceSyncBinaryAsset: (basePath, asset, workspaceId = 'default', options) => writeWorkspaceSyncBinaryAsset(deps, basePath, asset, workspaceId, options),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
|
|
2
|
-
import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
|
|
2
|
+
import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncChange, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncTaskEventSnapshot, WorkspaceSyncTaskSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
|
|
3
3
|
import type { BinaryAssetSyncPayload, DocumentSyncPayload } from './contentSyncPayload.js';
|
|
4
|
+
import type { AiProfileSurfaceType } from '../shared/aiProfileSurfaceType.js';
|
|
4
5
|
type SyncCore = TaskforceCore & TaskforceSyncCapable;
|
|
5
6
|
type SyncRouteError = Error & {
|
|
6
7
|
code?: string;
|
|
@@ -12,7 +13,81 @@ type CreateSyncRouteError = (message: string, details: Record<string, unknown>,
|
|
|
12
13
|
code?: string;
|
|
13
14
|
statusCode?: number;
|
|
14
15
|
}) => SyncRouteError;
|
|
16
|
+
type NormalizeIncomingAiProfileSurfaceType = (value: unknown, context: {
|
|
17
|
+
source: string;
|
|
18
|
+
profileId?: string;
|
|
19
|
+
workspaceId?: string;
|
|
20
|
+
}) => AiProfileSurfaceType | null;
|
|
21
|
+
type NormalizeTaskEventSyncPayload = (raw: unknown, workspaceId: string, sourceWatermark?: string) => WorkspaceSyncTaskEventSnapshot | null;
|
|
22
|
+
export interface WorkspaceSyncIncomingTaskMutation {
|
|
23
|
+
archived: boolean;
|
|
24
|
+
task: WorkspaceSyncTaskSnapshot;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkspaceSyncIncomingTaskApplyModel {
|
|
27
|
+
upserts: WorkspaceSyncIncomingTaskMutation[];
|
|
28
|
+
deletes: Map<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export interface WorkspaceSyncIncomingApplyModel {
|
|
31
|
+
taskMutations: WorkspaceSyncIncomingTaskApplyModel;
|
|
32
|
+
planning: {
|
|
33
|
+
incomingTaxonomies: unknown[] | null;
|
|
34
|
+
incomingTaxonomyState: Record<string, unknown> | null;
|
|
35
|
+
incomingTaxonomiesUpdatedAt: string;
|
|
36
|
+
incomingInitiatives: Map<string, WorkspaceSyncInitiativeSnapshot>;
|
|
37
|
+
incomingWorkstreams: Map<string, WorkspaceSyncWorkstreamSnapshot>;
|
|
38
|
+
};
|
|
39
|
+
profiles: {
|
|
40
|
+
incomingAiProfiles: Map<string, WorkspaceSyncAiProfileSnapshot>;
|
|
41
|
+
};
|
|
42
|
+
content: {
|
|
43
|
+
incomingDocuments: DocumentSyncPayload[];
|
|
44
|
+
incomingDocumentDeletes: Map<string, string>;
|
|
45
|
+
incomingAssets: BinaryAssetSyncPayload[];
|
|
46
|
+
incomingAssetDeletes: Map<string, string>;
|
|
47
|
+
};
|
|
48
|
+
collaboration: {
|
|
49
|
+
incomingDocumentReviewSessions: Map<string, WorkspaceSyncDocumentReviewSessionSnapshot>;
|
|
50
|
+
incomingDocumentReviewSessionDeletes: Map<string, string>;
|
|
51
|
+
incomingDocumentReviewComments: Map<string, WorkspaceSyncDocumentReviewCommentSnapshot>;
|
|
52
|
+
incomingDocumentReviewCommentDeletes: Map<string, string>;
|
|
53
|
+
incomingAnnotatedAttachmentSessions: Map<string, WorkspaceSyncAnnotatedAttachmentSessionSnapshot>;
|
|
54
|
+
incomingAnnotatedAttachmentSessionDeletes: Map<string, string>;
|
|
55
|
+
};
|
|
56
|
+
taskActivity: {
|
|
57
|
+
incomingTaskEvents: Map<string, WorkspaceSyncTaskEventSnapshot>;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface PreparedWorkspaceTaskSyncSnapshot {
|
|
61
|
+
tasks: WorkspaceSyncTaskSnapshot[];
|
|
62
|
+
archived: WorkspaceSyncTaskSnapshot[];
|
|
63
|
+
}
|
|
15
64
|
export declare function resolveSyncConflictOrdering(incomingWatermark: string, existingWatermark: string, incomingTieBreak: string, existingTieBreak: string): number;
|
|
65
|
+
export declare function classifyWorkspaceSyncChanges(input: {
|
|
66
|
+
workspaceId: string;
|
|
67
|
+
incomingChanges: WorkspaceSyncChange[];
|
|
68
|
+
normalizeWorkspaceSyncDocumentPath: (rawPath: unknown) => string | null;
|
|
69
|
+
normalizeTaskAssetPath: (rawPath: unknown) => string | null;
|
|
70
|
+
normalizeIncomingAiProfileSurfaceType: NormalizeIncomingAiProfileSurfaceType;
|
|
71
|
+
normalizeTaskEventSyncPayload: NormalizeTaskEventSyncPayload;
|
|
72
|
+
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
73
|
+
}): WorkspaceSyncIncomingApplyModel;
|
|
74
|
+
export declare function prepareTaskSyncSnapshotApply(input: {
|
|
75
|
+
core: SyncCore;
|
|
76
|
+
workspaceId: string;
|
|
77
|
+
taskMutations: WorkspaceSyncIncomingTaskApplyModel;
|
|
78
|
+
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
79
|
+
}): PreparedWorkspaceTaskSyncSnapshot;
|
|
80
|
+
export declare function applyTaskSyncDeletes(input: {
|
|
81
|
+
core: SyncCore;
|
|
82
|
+
workspaceId: string;
|
|
83
|
+
taskMutations: WorkspaceSyncIncomingTaskApplyModel;
|
|
84
|
+
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
85
|
+
}): number;
|
|
86
|
+
export declare function applyPreparedTaskSyncSnapshot(input: {
|
|
87
|
+
core: SyncCore;
|
|
88
|
+
workspaceId: string;
|
|
89
|
+
prepared: PreparedWorkspaceTaskSyncSnapshot;
|
|
90
|
+
}): ReturnType<SyncCore['applyWorkspaceSyncSnapshot']>;
|
|
16
91
|
export declare function applyPlanningSyncChanges(input: {
|
|
17
92
|
core: SyncCore;
|
|
18
93
|
workspaceId: string;
|
|
@@ -51,6 +126,10 @@ export declare function applyContentSyncChanges(input: {
|
|
|
51
126
|
hasBinaryAssetSyncMetadataDrift: (workspaceId: string, asset: BinaryAssetSyncPayload, options?: {
|
|
52
127
|
allowReferenceNumberReassignment?: boolean;
|
|
53
128
|
}) => boolean;
|
|
129
|
+
getExistingDocument?: (docPath: string, workspaceId: string) => {
|
|
130
|
+
updatedAt?: string | null;
|
|
131
|
+
contentHash?: string | null;
|
|
132
|
+
} | null;
|
|
54
133
|
writeWorkspaceSyncDocument: (basePath: string, doc: DocumentSyncPayload, workspaceId?: string, options?: {
|
|
55
134
|
allowReferenceNumberReassignment?: boolean;
|
|
56
135
|
}) => Promise<void>;
|
|
@@ -80,4 +159,11 @@ export declare function applyCollaborationSyncChanges(input: {
|
|
|
80
159
|
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
81
160
|
createSyncRouteError: CreateSyncRouteError;
|
|
82
161
|
}): void;
|
|
162
|
+
export declare function applyTaskActivitySyncChanges(input: {
|
|
163
|
+
core: SyncCore;
|
|
164
|
+
workspaceId: string;
|
|
165
|
+
incomingTaskEvents: Map<string, WorkspaceSyncTaskEventSnapshot>;
|
|
166
|
+
recordSyncDiagnostic: RecordSyncDiagnostic;
|
|
167
|
+
createSyncRouteError: CreateSyncRouteError;
|
|
168
|
+
}): void;
|
|
83
169
|
export {};
|