@taskforcehq/taskforce 0.3.303 → 0.3.305

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/README.md +140 -247
  2. package/dist/Taskforce.module.css +102 -5
  3. package/dist/TaskforceCore.js +635 -238
  4. package/dist/TaskforceCore.test.js +2243 -495
  5. package/dist/annotatedAttachments/service.d.ts +1 -1
  6. package/dist/annotatedAttachments/types.d.ts +1 -1
  7. package/dist/compat/workspaceSyncCompat.js +6 -0
  8. package/dist/components/features/AgentsModule.js +1 -1
  9. package/dist/components/features/AgentsModule.test.js +1 -1
  10. package/dist/components/features/DocumentIndex.d.ts +1 -1
  11. package/dist/components/features/DocumentIndex.js +1 -1
  12. package/dist/components/features/DocumentViewer.d.ts +1 -1
  13. package/dist/components/features/DocumentViewer.js +32 -9
  14. package/dist/components/features/DocumentWorkspace.d.ts +5 -22
  15. package/dist/components/features/DocumentWorkspace.js +12 -155
  16. package/dist/components/features/DocumentWorkspace.test.js +193 -6
  17. package/dist/components/features/TaskSettings.js +87 -41
  18. package/dist/components/features/TaskSettings.test.js +180 -40
  19. package/dist/components/features/documentWorkspaceModel.d.ts +24 -0
  20. package/dist/components/features/documentWorkspaceModel.js +57 -0
  21. package/dist/components/features/useDocumentWorkspaceController.d.ts +34 -0
  22. package/dist/components/features/useDocumentWorkspaceController.js +113 -0
  23. package/dist/components/task/TaskActionHeader.d.ts +2 -1
  24. package/dist/components/task/TaskActionHeader.js +3 -3
  25. package/dist/components/task/TaskActionHeader.test.js +8 -0
  26. package/dist/components/task/TaskCard.js +16 -1
  27. package/dist/components/task/TaskCard.test.js +31 -0
  28. package/dist/components/task/TaskForm.d.ts +9 -8
  29. package/dist/components/task/TaskForm.js +374 -219
  30. package/dist/components/task/TaskForm.test.js +482 -361
  31. package/dist/components/task/TaskKanban.d.ts +1 -1
  32. package/dist/components/task/TaskKanban.js +33 -161
  33. package/dist/components/task/TaskStatusActions.d.ts +6 -1
  34. package/dist/components/task/TaskStatusActions.js +8 -3
  35. package/dist/components/task/TaskStatusActions.test.js +9 -0
  36. package/dist/components/task/taskKanbanDropRules.d.ts +58 -0
  37. package/dist/components/task/taskKanbanDropRules.js +187 -0
  38. package/dist/components/task/taskKanbanDropRules.test.d.ts +1 -0
  39. package/dist/components/task/taskKanbanDropRules.test.js +114 -0
  40. package/dist/components/ui/Modal.d.ts +1 -1
  41. package/dist/components/ui/Modal.js +1 -0
  42. package/dist/components/views/AppShellHeader.js +5 -1
  43. package/dist/components/views/AppShellHeader.test.js +4 -0
  44. package/dist/components/views/PlanComparisonPage.d.ts +3 -2
  45. package/dist/components/views/PlanComparisonPage.js +9 -10
  46. package/dist/components/views/PlanComparisonPage.test.js +55 -41
  47. package/dist/components/views/PlansPage.d.ts +5 -1
  48. package/dist/components/views/PlansPage.js +150 -81
  49. package/dist/components/views/PlansPage.test.js +367 -41
  50. package/dist/components/views/StandaloneLayout.js +135 -54
  51. package/dist/components/views/WidgetView.js +11 -2
  52. package/dist/components/views/panels/FilterToolbar.test.js +6 -4
  53. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +2 -14
  54. package/dist/components/views/standalone/modals/AccountHubModal.js +12 -14
  55. package/dist/components/views/standalone/modals/AccountHubModal.test.js +24 -1
  56. package/dist/components/views/standalone/modals/SyncStatusModal.js +1 -1
  57. package/dist/config/envSchema.js +1 -1
  58. package/dist/core/AiProfileService.d.ts +6 -1
  59. package/dist/core/AiProfileService.js +161 -16
  60. package/dist/core/AiProfileService.test.js +3 -1
  61. package/dist/core/AiProfiles.test.js +200 -0
  62. package/dist/core/AuthTokenService.test.d.ts +1 -0
  63. package/dist/core/AuthTokenService.test.js +78 -0
  64. package/dist/core/DeletedTaskLifecycleService.d.ts +2 -1
  65. package/dist/core/EntitlementsPolicy.test.js +75 -13
  66. package/dist/core/PlanEntitlementService.d.ts +9 -1
  67. package/dist/core/PlanEntitlementService.js +144 -19
  68. package/dist/core/PlanVersionPolicy.test.js +19 -26
  69. package/dist/core/SignupMonetizationSettings.test.js +75 -15
  70. package/dist/core/SystemAdmin.test.js +212 -56
  71. package/dist/core/TaskActivityService.d.ts +4 -1
  72. package/dist/core/TaskActivityService.js +45 -0
  73. package/dist/core/TaskAuditTimeline.test.js +52 -1
  74. package/dist/core/TaskTaxonomyValidation.test.js +53 -0
  75. package/dist/core/Taskforce.d.ts +18 -11
  76. package/dist/core/Taskforce.js +93 -12
  77. package/dist/core/WorkspacePlanMode.test.js +73 -8
  78. package/dist/core/shared.d.ts +2 -0
  79. package/dist/core/shared.js +11 -0
  80. package/dist/documentReviews/service.d.ts +1 -1
  81. package/dist/documentReviews/types.d.ts +1 -1
  82. package/dist/hooks/auth/useTaskforceAuthBootstrap.d.ts +48 -0
  83. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +219 -0
  84. package/dist/hooks/sync/auth.d.ts +37 -0
  85. package/dist/hooks/sync/auth.js +63 -0
  86. package/dist/hooks/sync/bootstrap.d.ts +34 -0
  87. package/dist/hooks/sync/bootstrap.js +52 -0
  88. package/dist/hooks/sync/orchestratorShared.d.ts +36 -0
  89. package/dist/hooks/sync/orchestratorShared.js +209 -0
  90. package/dist/hooks/sync/orchestratorShared.test.d.ts +1 -0
  91. package/dist/hooks/sync/orchestratorShared.test.js +49 -0
  92. package/dist/hooks/sync/realtime.d.ts +25 -0
  93. package/dist/hooks/sync/realtime.js +60 -0
  94. package/dist/hooks/sync/recovery.d.ts +69 -0
  95. package/dist/hooks/sync/recovery.js +118 -0
  96. package/dist/hooks/sync/transfers.d.ts +123 -0
  97. package/dist/hooks/sync/transfers.js +435 -0
  98. package/dist/hooks/sync/useDataVersionRefresh.d.ts +16 -0
  99. package/dist/hooks/sync/useDataVersionRefresh.js +73 -0
  100. package/dist/hooks/ui/useResourceExport.d.ts +3 -1
  101. package/dist/hooks/ui/useResourceExport.js +5 -2
  102. package/dist/hooks/ui/useWorkflowTemplates.js +11 -6
  103. package/dist/hooks/useRealtimeSync.js +2 -1
  104. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +8 -0
  105. package/dist/hooks/useSyncOrchestrator.context-assets.test.d.ts +1 -0
  106. package/dist/hooks/useSyncOrchestrator.context-assets.test.js +228 -0
  107. package/dist/hooks/useSyncOrchestrator.d.ts +12 -8
  108. package/dist/hooks/useSyncOrchestrator.js +388 -879
  109. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +641 -6
  110. package/dist/hooks/useTaskMutations.d.ts +2 -1
  111. package/dist/hooks/useTaskMutations.js +57 -7
  112. package/dist/hooks/useTaskMutations.test.js +176 -0
  113. package/dist/hooks/useTaskforce.d.ts +13 -4
  114. package/dist/hooks/useTaskforce.js +302 -817
  115. package/dist/hooks/useTaskforce.sync-behavior.test.js +78 -0
  116. package/dist/hooks/useWorkspaceSyncController.d.ts +4 -1
  117. package/dist/hooks/useWorkspaceSyncController.js +33 -11
  118. package/dist/hooks/useWorkspaceSyncController.test.js +1 -0
  119. package/dist/hooks/workspace/useTaskforceApiRouting.test.js +17 -0
  120. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +166 -0
  121. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +434 -0
  122. package/dist/hooks/workspace/workspaceLocalState.d.ts +19 -0
  123. package/dist/hooks/workspace/workspaceLocalState.js +100 -0
  124. package/dist/hooks/workspace/workspaceLocalState.test.d.ts +1 -0
  125. package/dist/hooks/workspace/workspaceLocalState.test.js +59 -0
  126. package/dist/localization/locales/en-US.js +2 -2
  127. package/dist/mcp/adminWorkspaceRegistrar.d.ts +2 -0
  128. package/dist/mcp/adminWorkspaceRegistrar.js +154 -0
  129. package/dist/mcp/canonicalAssetHelpers.d.ts +70 -0
  130. package/dist/mcp/canonicalAssetHelpers.js +259 -0
  131. package/dist/mcp/clientIntegrations.d.ts +12 -1
  132. package/dist/mcp/clientIntegrations.js +161 -6
  133. package/dist/mcp/clientIntegrations.test.js +76 -4
  134. package/dist/mcp/collaborationRegistrar.d.ts +2 -0
  135. package/dist/mcp/collaborationRegistrar.js +71 -0
  136. package/dist/mcp/documentAssetRegistrar.d.ts +2 -0
  137. package/dist/mcp/documentAssetRegistrar.js +346 -0
  138. package/dist/mcp/documentHelpers.d.ts +100 -0
  139. package/dist/mcp/documentHelpers.js +161 -0
  140. package/dist/mcp/runtime.js +2455 -3925
  141. package/dist/mcp/runtime.test.js +240 -8
  142. package/dist/mcp/taskAttachmentHelpers.d.ts +41 -0
  143. package/dist/mcp/taskAttachmentHelpers.js +60 -0
  144. package/dist/mcp/taskAttachmentTypes.d.ts +37 -0
  145. package/dist/mcp/taskAttachmentTypes.js +1 -0
  146. package/dist/mcp/taskPlanningRegistrar.d.ts +2 -0
  147. package/dist/mcp/taskPlanningRegistrar.js +418 -0
  148. package/dist/mcp/toolCatalog.d.ts +35 -0
  149. package/dist/mcp/toolCatalog.js +3 -0
  150. package/dist/plugins/vite.js +1 -1
  151. package/dist/runtime/appGateDefinitions.d.ts +1 -1
  152. package/dist/runtime/appGateDefinitions.js +1 -1
  153. package/dist/server/index.d.ts +1 -0
  154. package/dist/server/index.js +46 -3
  155. package/dist/server/index.test.js +12 -1
  156. package/dist/server/routes/admin.d.ts +1 -5
  157. package/dist/server/routes/admin.js +151 -80
  158. package/dist/server/routes/annotatedAttachments.d.ts +1 -1
  159. package/dist/server/routes/annotatedAttachments.js +1 -1
  160. package/dist/server/routes/auth.d.ts +1 -4
  161. package/dist/server/routes/auth.js +59 -64
  162. package/dist/server/routes/authSupport.d.ts +30 -0
  163. package/dist/server/routes/authSupport.js +81 -0
  164. package/dist/server/routes/billing.d.ts +1 -1
  165. package/dist/server/routes/billing.js +122 -255
  166. package/dist/server/routes/billing.test.js +257 -86
  167. package/dist/server/routes/documentReviews.d.ts +1 -1
  168. package/dist/server/routes/documentReviews.js +1 -1
  169. package/dist/server/routes/documents.d.ts +4 -2
  170. package/dist/server/routes/documents.js +73 -7
  171. package/dist/server/routes/primitives.d.ts +11 -0
  172. package/dist/server/routes/primitives.js +73 -0
  173. package/dist/server/routes/resources.d.ts +1 -1
  174. package/dist/server/routes/resources.js +1 -1
  175. package/dist/server/routes/shared.d.ts +31 -1
  176. package/dist/server/routes/shared.js +26 -0
  177. package/dist/server/routes/sync.d.ts +1 -1
  178. package/dist/server/routes/sync.integration.test.js +20 -0
  179. package/dist/server/routes/sync.js +111 -238
  180. package/dist/server/routes/tasks.d.ts +1 -1
  181. package/dist/server/routes/tasks.js +50 -8
  182. package/dist/server/routes/workspaces.d.ts +1 -1
  183. package/dist/server/routes/workspaces.js +1 -1
  184. package/dist/server/routes.d.ts +2 -9
  185. package/dist/server/routes.js +84 -181
  186. package/dist/server/routes.test.js +912 -32
  187. package/dist/shared/taskActor.d.ts +10 -0
  188. package/dist/shared/taskActor.js +1 -0
  189. package/dist/sync/collaborationSyncPayload.js +4 -0
  190. package/dist/sync/collaborationSyncPayload.test.js +8 -0
  191. package/dist/sync/collaborationSyncState.d.ts +3 -1
  192. package/dist/sync/collaborationSyncState.js +19 -0
  193. package/dist/sync/contentSyncState.js +28 -17
  194. package/dist/sync/syncApplyHandlers.d.ts +87 -1
  195. package/dist/sync/syncApplyHandlers.js +370 -8
  196. package/dist/sync/syncApplyHandlers.test.d.ts +1 -0
  197. package/dist/sync/syncApplyHandlers.test.js +379 -0
  198. package/dist/sync/syncService.d.ts +9 -1
  199. package/dist/sync/syncService.js +44 -2
  200. package/dist/sync/syncService.test.js +62 -0
  201. package/dist/sync/workspacePullFeed.d.ts +1 -0
  202. package/dist/sync/workspacePullFeed.js +66 -59
  203. package/dist/sync/workspacePullFeed.test.js +72 -4
  204. package/dist/sync/workspaceSyncModel.d.ts +25 -1
  205. package/dist/sync/workspaceSyncModel.js +77 -3
  206. package/dist/sync/workspaceSyncModel.test.js +153 -0
  207. package/dist/sync/workspaceSyncState.d.ts +2 -0
  208. package/dist/sync/workspaceSyncState.js +1 -0
  209. package/dist/types.d.ts +2 -10
  210. package/dist/ui/assets/AgentsModule-N2MnQBZk.js +1 -0
  211. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-C_TmXZwA.js → AnnotatedAttachmentWorkspace-BG6P_GVW.js} +1 -1
  212. package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +1 -0
  213. package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +252 -0
  214. package/dist/ui/assets/{InitiativesModule-4-Rh2K2n.js → InitiativesModule-Dhm7M8e7.js} +1 -1
  215. package/dist/ui/assets/{PlansPage-BlVC_lRq.css → PlansPage-C2dd2n1X.css} +1 -1
  216. package/dist/ui/assets/PlansPage-Cq0zXj3I.js +1 -0
  217. package/dist/ui/assets/TaskSettings-ln0aF7xc.js +9 -0
  218. package/dist/ui/assets/{WorkflowsModule-CGk9s3NJ.js → WorkflowsModule-BcS4afRn.js} +1 -1
  219. package/dist/ui/assets/index-C2-OXZV7.css +1 -0
  220. package/dist/ui/assets/index-DcSI5F86.js +6 -0
  221. package/dist/ui/assets/{vendor-icons-pWocEipT.js → vendor-icons-BSUaRwF8.js} +1 -1
  222. package/dist/ui/index.html +4 -4
  223. package/dist/utils/commercialLifecyclePresentation.d.ts +19 -0
  224. package/dist/utils/commercialLifecyclePresentation.js +196 -0
  225. package/dist/utils/taskActivity.js +4 -0
  226. package/dist/utils/taskActivity.test.js +25 -1
  227. package/package.json +10 -1
  228. package/scripts/check-cloud-mcp.mjs +83 -0
  229. package/scripts/playwright-auth.sh +9 -1
  230. package/scripts/run-billing-performance-smoke.sh +24 -0
  231. package/dist/ui/assets/AgentsModule-CpsTmrIW.js +0 -1
  232. package/dist/ui/assets/DocumentWorkspace-C3GyzrWm.js +0 -250
  233. package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +0 -1
  234. package/dist/ui/assets/PlansPage-BP7AYOqr.js +0 -1
  235. package/dist/ui/assets/TaskSettings-BOC5F6Ag.js +0 -8
  236. package/dist/ui/assets/index-CLIMgR6g.js +0 -6
  237. package/dist/ui/assets/index-DneETxcu.css +0 -1
@@ -0,0 +1,49 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { readPersistedSyncWatermarks, savePersistedSyncWatermarks, WORKSPACE_SYNC_WATERMARKS_KEY_PREFIX, } from './orchestratorShared';
3
+ describe('orchestratorShared sync watermarks', () => {
4
+ const workspaceId = 'workspace-local-active';
5
+ beforeEach(() => {
6
+ localStorage.clear();
7
+ });
8
+ it('keeps persisted sync watermarks available across long idle periods', () => {
9
+ const key = `${WORKSPACE_SYNC_WATERMARKS_KEY_PREFIX}.${workspaceId}`;
10
+ localStorage.setItem(key, JSON.stringify({
11
+ v: 8,
12
+ savedAt: '2026-04-14T10:00:00.000Z',
13
+ taskWatermarks: [['task-1', '2026-04-14T09:00:00.000Z']],
14
+ initiativeWatermarks: [['initiative-1', '2026-04-14T09:00:00.000Z']],
15
+ workstreamWatermarks: [],
16
+ documentWatermarks: [],
17
+ assetWatermarks: [],
18
+ documentReviewSessionWatermarks: [],
19
+ documentReviewCommentWatermarks: [],
20
+ annotatedAttachmentSessionWatermarks: [],
21
+ taskEventWatermarks: [['event-1', '2026-04-14T09:30:00.000Z']],
22
+ taxonomyStateFingerprint: ''
23
+ }));
24
+ const persisted = readPersistedSyncWatermarks(workspaceId, '');
25
+ expect(persisted).not.toBeNull();
26
+ expect(persisted?.taskWatermarks.get('task-1')).toBe('2026-04-14T09:00:00.000Z');
27
+ expect(persisted?.initiativeWatermarks.get('initiative-1')).toBe('2026-04-14T09:00:00.000Z');
28
+ expect(persisted?.taskEventWatermarks.get('event-1')).toBe('2026-04-14T09:30:00.000Z');
29
+ });
30
+ it('still clears task watermarks when the taxonomy fingerprint changes', () => {
31
+ savePersistedSyncWatermarks(workspaceId, {
32
+ taskWatermarks: new Map([['task-1', '2026-04-14T09:00:00.000Z']]),
33
+ initiativeWatermarks: new Map([['initiative-1', '2026-04-14T09:00:00.000Z']]),
34
+ workstreamWatermarks: new Map(),
35
+ documentWatermarks: new Map(),
36
+ assetWatermarks: new Map(),
37
+ documentReviewSessionWatermarks: new Map(),
38
+ documentReviewCommentWatermarks: new Map(),
39
+ annotatedAttachmentSessionWatermarks: new Map(),
40
+ taskEventWatermarks: new Map([['event-1', '2026-04-14T09:30:00.000Z']]),
41
+ taxonomyStateFingerprint: 'fingerprint-a'
42
+ });
43
+ const persisted = readPersistedSyncWatermarks(workspaceId, 'fingerprint-b');
44
+ expect(persisted).not.toBeNull();
45
+ expect(persisted?.taskWatermarks.size).toBe(0);
46
+ expect(persisted?.initiativeWatermarks.get('initiative-1')).toBe('2026-04-14T09:00:00.000Z');
47
+ expect(persisted?.taskEventWatermarks.get('event-1')).toBe('2026-04-14T09:30:00.000Z');
48
+ });
49
+ });
@@ -0,0 +1,25 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import type { WorkspaceSyncPhase } from '../../sync/workspaceSyncState';
3
+ import type { RealtimeSyncSignal } from '../useRealtimeSync';
4
+ interface CreateRealtimeSyncBridgeArgs {
5
+ cloudAuthConfigured: boolean;
6
+ runtimeMode: 'local' | 'cloud';
7
+ workspaceCloudSyncEnabled: boolean;
8
+ workspaceSyncPhase: WorkspaceSyncPhase;
9
+ workspacePullInFlightRef: MutableRefObject<boolean>;
10
+ realtimePullDebounceRef: MutableRefObject<number | null>;
11
+ realtimeSuppressedEventIdsRef: MutableRefObject<Set<string>>;
12
+ clearWorkspaceRetry: () => void;
13
+ isWorkspaceRetryPending: () => boolean;
14
+ pullWorkspaceChangesFromCloud: () => Promise<boolean>;
15
+ }
16
+ export declare function createRealtimeSyncBridge({ cloudAuthConfigured, runtimeMode, workspaceCloudSyncEnabled, workspaceSyncPhase, workspacePullInFlightRef, realtimePullDebounceRef, realtimeSuppressedEventIdsRef, clearWorkspaceRetry, isWorkspaceRetryPending, pullWorkspaceChangesFromCloud }: CreateRealtimeSyncBridgeArgs): {
17
+ handleRealtimeSignal: (signal: RealtimeSyncSignal) => void;
18
+ recordSuppressedEventIds: (eventIds: Iterable<string>, options?: {
19
+ queueRef?: MutableRefObject<string[]>;
20
+ maxQueueSize?: number;
21
+ ttlMs?: number;
22
+ }) => void;
23
+ clearRealtimePullDebounce: () => void;
24
+ };
25
+ export {};
@@ -0,0 +1,60 @@
1
+ export function createRealtimeSyncBridge({ cloudAuthConfigured, runtimeMode, workspaceCloudSyncEnabled, workspaceSyncPhase, workspacePullInFlightRef, realtimePullDebounceRef, realtimeSuppressedEventIdsRef, clearWorkspaceRetry, isWorkspaceRetryPending, pullWorkspaceChangesFromCloud }) {
2
+ const handleRealtimeSignal = (signal) => {
3
+ if (!cloudAuthConfigured || runtimeMode !== 'local' || !workspaceCloudSyncEnabled)
4
+ return;
5
+ if (workspaceSyncPhase === 'provision-local')
6
+ return;
7
+ const eventId = String(signal?.eventId || '').trim();
8
+ if (eventId && realtimeSuppressedEventIdsRef.current.delete(eventId))
9
+ return;
10
+ if (workspacePullInFlightRef.current)
11
+ return;
12
+ if (isWorkspaceRetryPending()) {
13
+ clearWorkspaceRetry();
14
+ }
15
+ if (realtimePullDebounceRef.current !== null) {
16
+ window.clearTimeout(realtimePullDebounceRef.current);
17
+ }
18
+ realtimePullDebounceRef.current = window.setTimeout(() => {
19
+ realtimePullDebounceRef.current = null;
20
+ void pullWorkspaceChangesFromCloud();
21
+ }, 180);
22
+ };
23
+ const recordSuppressedEventIds = (eventIds, options) => {
24
+ const queueRef = options?.queueRef;
25
+ const maxQueueSize = Number.isFinite(options?.maxQueueSize) ? Math.max(1, Number(options?.maxQueueSize)) : 2048;
26
+ const ttlMs = Number.isFinite(options?.ttlMs) ? Math.max(0, Number(options?.ttlMs)) : null;
27
+ for (const rawEventId of eventIds) {
28
+ const eventId = String(rawEventId || '').trim();
29
+ if (!eventId || realtimeSuppressedEventIdsRef.current.has(eventId))
30
+ continue;
31
+ realtimeSuppressedEventIdsRef.current.add(eventId);
32
+ if (queueRef) {
33
+ queueRef.current.push(eventId);
34
+ }
35
+ if (ttlMs !== null) {
36
+ window.setTimeout(() => {
37
+ realtimeSuppressedEventIdsRef.current.delete(eventId);
38
+ }, ttlMs);
39
+ }
40
+ }
41
+ if (queueRef) {
42
+ while (queueRef.current.length > maxQueueSize) {
43
+ const stale = queueRef.current.shift();
44
+ if (stale)
45
+ realtimeSuppressedEventIdsRef.current.delete(stale);
46
+ }
47
+ }
48
+ };
49
+ const clearRealtimePullDebounce = () => {
50
+ if (realtimePullDebounceRef.current !== null) {
51
+ window.clearTimeout(realtimePullDebounceRef.current);
52
+ realtimePullDebounceRef.current = null;
53
+ }
54
+ };
55
+ return {
56
+ handleRealtimeSignal,
57
+ recordSuppressedEventIds,
58
+ clearRealtimePullDebounce
59
+ };
60
+ }
@@ -0,0 +1,69 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import type { WorkspaceSyncPhase } from '../../sync/workspaceSyncState';
3
+ interface CreateSyncRecoveryCoordinatorArgs {
4
+ currentWorkspaceId: string;
5
+ taxonomyStateFingerprint: string;
6
+ workspaceCloudSyncEnabled: boolean;
7
+ workspaceSyncPhase: WorkspaceSyncPhase;
8
+ workspaceLastPullAt: string | null;
9
+ lastBootstrapPhaseRef: MutableRefObject<WorkspaceSyncPhase>;
10
+ workspaceRepairModeRef: MutableRefObject<boolean>;
11
+ workspaceForceFullAiProfilePushRef: MutableRefObject<boolean>;
12
+ workspaceStartupRepairRanRef: MutableRefObject<boolean>;
13
+ workspaceStartupFullReconcileRanRef: MutableRefObject<boolean>;
14
+ workspaceFullReconcileInFlightRef: MutableRefObject<boolean>;
15
+ workspacePullCursorRef: MutableRefObject<string | null>;
16
+ workspaceAttachBootstrapBaselineSignatureRef: MutableRefObject<string>;
17
+ workspaceCaptureAttachBootstrapBaselineRef: MutableRefObject<boolean>;
18
+ workspacePendingSignatureRef: MutableRefObject<string>;
19
+ workspaceLastPushedSignatureRef: MutableRefObject<string>;
20
+ workspaceLastPushedWatermarksRef: MutableRefObject<Map<string, string>>;
21
+ workspaceLastPushedInitiativeIdsRef: MutableRefObject<Set<string>>;
22
+ workspaceLastPushedInitiativeWatermarksRef: MutableRefObject<Map<string, string>>;
23
+ workspaceLastPushedWorkstreamIdsRef: MutableRefObject<Set<string>>;
24
+ workspaceLastPushedWorkstreamWatermarksRef: MutableRefObject<Map<string, string>>;
25
+ workspaceLastPushedAiProfileIdsRef: MutableRefObject<Set<string>>;
26
+ workspaceLastPushedAiProfileWatermarksRef: MutableRefObject<Map<string, string>>;
27
+ workspaceLastPushedDocumentPathsRef: MutableRefObject<Set<string>>;
28
+ workspaceLastPushedDocumentWatermarksRef: MutableRefObject<Map<string, string>>;
29
+ workspaceLastPushedAssetPathsRef: MutableRefObject<Set<string>>;
30
+ workspaceLastPushedAssetWatermarksRef: MutableRefObject<Map<string, string>>;
31
+ workspaceLastPushedDocumentReviewSessionIdsRef: MutableRefObject<Set<string>>;
32
+ workspaceLastPushedDocumentReviewSessionWatermarksRef: MutableRefObject<Map<string, string>>;
33
+ workspaceLastPushedDocumentReviewCommentIdsRef: MutableRefObject<Set<string>>;
34
+ workspaceLastPushedDocumentReviewCommentWatermarksRef: MutableRefObject<Map<string, string>>;
35
+ workspaceLastPushedAnnotatedAttachmentSessionIdsRef: MutableRefObject<Set<string>>;
36
+ workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef: MutableRefObject<Map<string, string>>;
37
+ workspaceLastPushedTaskEventWatermarksRef: MutableRefObject<Map<string, string>>;
38
+ bootstrapPhaseStartedAtRef: MutableRefObject<number | null>;
39
+ bootstrapLastProgressAtRef: MutableRefObject<number | null>;
40
+ acquireWorkspaceSyncLease: (workspaceId: string, owner: 'pull' | 'push' | 'repair') => Promise<boolean>;
41
+ releaseWorkspaceSyncLease: (workspaceId: string) => void;
42
+ forceClearWorkspaceSyncLease: (workspaceId: string) => void;
43
+ clearWorkspaceRetry: () => void;
44
+ clearWorkspaceIssue: () => void;
45
+ reportWorkspaceWindowContention: (operation: 'pull' | 'push' | 'repair') => void;
46
+ persistWorkspaceSyncPatch: (patch: {
47
+ phase: WorkspaceSyncPhase;
48
+ pullCursor: null;
49
+ lastErrorMessage: null;
50
+ }) => Promise<unknown>;
51
+ buildWorkspaceSyncSignature: () => string;
52
+ pullWorkspaceChangesFromCloud: (options?: {
53
+ repairMode?: boolean;
54
+ forceCursorNull?: boolean;
55
+ }) => Promise<boolean>;
56
+ pushWorkspaceChangesToCloud: (signature: string, options?: {
57
+ forceAllAiProfiles?: boolean;
58
+ repairMode?: boolean;
59
+ }) => Promise<boolean>;
60
+ cloudAuthConfigured: boolean;
61
+ runtimeMode: 'local' | 'cloud';
62
+ isAuthenticated: boolean;
63
+ checkAuthSession: () => Promise<boolean>;
64
+ }
65
+ export declare function createSyncRecoveryCoordinator({ currentWorkspaceId, taxonomyStateFingerprint, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceLastPullAt, lastBootstrapPhaseRef, workspaceRepairModeRef, workspaceForceFullAiProfilePushRef, workspaceStartupRepairRanRef, workspaceStartupFullReconcileRanRef, workspaceFullReconcileInFlightRef, workspacePullCursorRef, workspaceAttachBootstrapBaselineSignatureRef, workspaceCaptureAttachBootstrapBaselineRef, workspacePendingSignatureRef, workspaceLastPushedSignatureRef, workspaceLastPushedWatermarksRef, workspaceLastPushedInitiativeIdsRef, workspaceLastPushedInitiativeWatermarksRef, workspaceLastPushedWorkstreamIdsRef, workspaceLastPushedWorkstreamWatermarksRef, workspaceLastPushedAiProfileIdsRef, workspaceLastPushedAiProfileWatermarksRef, workspaceLastPushedDocumentPathsRef, workspaceLastPushedDocumentWatermarksRef, workspaceLastPushedAssetPathsRef, workspaceLastPushedAssetWatermarksRef, workspaceLastPushedDocumentReviewSessionIdsRef, workspaceLastPushedDocumentReviewSessionWatermarksRef, workspaceLastPushedDocumentReviewCommentIdsRef, workspaceLastPushedDocumentReviewCommentWatermarksRef, workspaceLastPushedAnnotatedAttachmentSessionIdsRef, workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, workspaceLastPushedTaskEventWatermarksRef, bootstrapPhaseStartedAtRef, bootstrapLastProgressAtRef, acquireWorkspaceSyncLease, releaseWorkspaceSyncLease, forceClearWorkspaceSyncLease, clearWorkspaceRetry, clearWorkspaceIssue, reportWorkspaceWindowContention, persistWorkspaceSyncPatch, buildWorkspaceSyncSignature, pullWorkspaceChangesFromCloud, pushWorkspaceChangesToCloud, cloudAuthConfigured, runtimeMode, isAuthenticated, checkAuthSession }: CreateSyncRecoveryCoordinatorArgs): {
66
+ retryWorkspaceCloudSync: () => Promise<boolean>;
67
+ resetWorkspaceSyncCursorAndPull: () => Promise<void>;
68
+ };
69
+ export {};
@@ -0,0 +1,118 @@
1
+ import { resolveRepairPhase } from './bootstrap';
2
+ import { savePersistedSyncWatermarks } from './orchestratorShared';
3
+ export function createSyncRecoveryCoordinator({ currentWorkspaceId, taxonomyStateFingerprint, workspaceCloudSyncEnabled, workspaceSyncPhase, workspaceLastPullAt, lastBootstrapPhaseRef, workspaceRepairModeRef, workspaceForceFullAiProfilePushRef, workspaceStartupRepairRanRef, workspaceStartupFullReconcileRanRef, workspaceFullReconcileInFlightRef, workspacePullCursorRef, workspaceAttachBootstrapBaselineSignatureRef, workspaceCaptureAttachBootstrapBaselineRef, workspacePendingSignatureRef, workspaceLastPushedSignatureRef, workspaceLastPushedWatermarksRef, workspaceLastPushedInitiativeIdsRef, workspaceLastPushedInitiativeWatermarksRef, workspaceLastPushedWorkstreamIdsRef, workspaceLastPushedWorkstreamWatermarksRef, workspaceLastPushedAiProfileIdsRef, workspaceLastPushedAiProfileWatermarksRef, workspaceLastPushedDocumentPathsRef, workspaceLastPushedDocumentWatermarksRef, workspaceLastPushedAssetPathsRef, workspaceLastPushedAssetWatermarksRef, workspaceLastPushedDocumentReviewSessionIdsRef, workspaceLastPushedDocumentReviewSessionWatermarksRef, workspaceLastPushedDocumentReviewCommentIdsRef, workspaceLastPushedDocumentReviewCommentWatermarksRef, workspaceLastPushedAnnotatedAttachmentSessionIdsRef, workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, workspaceLastPushedTaskEventWatermarksRef, bootstrapPhaseStartedAtRef, bootstrapLastProgressAtRef, acquireWorkspaceSyncLease, releaseWorkspaceSyncLease, forceClearWorkspaceSyncLease, clearWorkspaceRetry, clearWorkspaceIssue, reportWorkspaceWindowContention, persistWorkspaceSyncPatch, buildWorkspaceSyncSignature, pullWorkspaceChangesFromCloud, pushWorkspaceChangesToCloud, cloudAuthConfigured, runtimeMode, isAuthenticated, checkAuthSession }) {
4
+ const retryWorkspaceCloudSync = async () => {
5
+ clearWorkspaceRetry();
6
+ if (!cloudAuthConfigured || runtimeMode !== 'local' || !workspaceCloudSyncEnabled)
7
+ return false;
8
+ if (!isAuthenticated) {
9
+ const authed = await checkAuthSession();
10
+ if (!authed)
11
+ return false;
12
+ }
13
+ workspaceForceFullAiProfilePushRef.current = true;
14
+ if (workspaceSyncPhase === 'provision-local') {
15
+ const signature = buildWorkspaceSyncSignature();
16
+ if (!signature)
17
+ return false;
18
+ return pushWorkspaceChangesToCloud(signature, { forceAllAiProfiles: true });
19
+ }
20
+ const pulled = await pullWorkspaceChangesFromCloud();
21
+ if (workspaceSyncPhase === 'attach-cloud')
22
+ return pulled;
23
+ const signature = buildWorkspaceSyncSignature();
24
+ if (signature) {
25
+ workspacePendingSignatureRef.current = signature;
26
+ const pushed = await pushWorkspaceChangesToCloud(signature, {
27
+ forceAllAiProfiles: workspaceForceFullAiProfilePushRef.current === true
28
+ });
29
+ return pulled || pushed;
30
+ }
31
+ return pulled;
32
+ };
33
+ const resetWorkspaceSyncCursorAndPull = async () => {
34
+ const leaseAcquired = await acquireWorkspaceSyncLease(currentWorkspaceId, 'repair');
35
+ if (!leaseAcquired) {
36
+ forceClearWorkspaceSyncLease(currentWorkspaceId);
37
+ const reclaimed = await acquireWorkspaceSyncLease(currentWorkspaceId, 'repair');
38
+ if (!reclaimed) {
39
+ reportWorkspaceWindowContention('repair');
40
+ return;
41
+ }
42
+ }
43
+ clearWorkspaceRetry();
44
+ clearWorkspaceIssue();
45
+ bootstrapPhaseStartedAtRef.current = null;
46
+ bootstrapLastProgressAtRef.current = null;
47
+ workspacePullCursorRef.current = null;
48
+ workspaceAttachBootstrapBaselineSignatureRef.current = '';
49
+ workspaceCaptureAttachBootstrapBaselineRef.current = false;
50
+ workspacePendingSignatureRef.current = '';
51
+ workspaceLastPushedSignatureRef.current = '';
52
+ workspaceLastPushedWatermarksRef.current = new Map();
53
+ workspaceLastPushedInitiativeIdsRef.current = new Set();
54
+ workspaceLastPushedInitiativeWatermarksRef.current = new Map();
55
+ workspaceLastPushedWorkstreamIdsRef.current = new Set();
56
+ workspaceLastPushedWorkstreamWatermarksRef.current = new Map();
57
+ workspaceLastPushedAiProfileIdsRef.current = new Set();
58
+ workspaceLastPushedAiProfileWatermarksRef.current = new Map();
59
+ workspaceLastPushedDocumentPathsRef.current = new Set();
60
+ workspaceLastPushedDocumentWatermarksRef.current = new Map();
61
+ workspaceLastPushedAssetPathsRef.current = new Set();
62
+ workspaceLastPushedAssetWatermarksRef.current = new Map();
63
+ workspaceLastPushedDocumentReviewSessionIdsRef.current = new Set();
64
+ workspaceLastPushedDocumentReviewSessionWatermarksRef.current = new Map();
65
+ workspaceLastPushedDocumentReviewCommentIdsRef.current = new Set();
66
+ workspaceLastPushedDocumentReviewCommentWatermarksRef.current = new Map();
67
+ workspaceLastPushedAnnotatedAttachmentSessionIdsRef.current = new Set();
68
+ workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef.current = new Map();
69
+ workspaceLastPushedTaskEventWatermarksRef.current = new Map();
70
+ workspaceForceFullAiProfilePushRef.current = false;
71
+ workspaceStartupRepairRanRef.current = false;
72
+ workspaceStartupFullReconcileRanRef.current = false;
73
+ workspaceFullReconcileInFlightRef.current = false;
74
+ savePersistedSyncWatermarks(currentWorkspaceId, {
75
+ taskWatermarks: new Map(),
76
+ initiativeWatermarks: new Map(),
77
+ workstreamWatermarks: new Map(),
78
+ documentWatermarks: new Map(),
79
+ assetWatermarks: new Map(),
80
+ documentReviewSessionWatermarks: new Map(),
81
+ documentReviewCommentWatermarks: new Map(),
82
+ annotatedAttachmentSessionWatermarks: new Map(),
83
+ taskEventWatermarks: new Map(),
84
+ taxonomyStateFingerprint
85
+ });
86
+ try {
87
+ if (!workspaceCloudSyncEnabled)
88
+ return;
89
+ workspaceRepairModeRef.current = true;
90
+ const repairPhase = resolveRepairPhase({
91
+ workspaceSyncPhase,
92
+ lastBootstrapPhase: lastBootstrapPhaseRef.current,
93
+ workspaceLastPullAt
94
+ });
95
+ await persistWorkspaceSyncPatch({
96
+ phase: repairPhase,
97
+ pullCursor: null,
98
+ lastErrorMessage: null
99
+ });
100
+ if (repairPhase === 'provision-local') {
101
+ const signature = buildWorkspaceSyncSignature();
102
+ if (!signature)
103
+ return;
104
+ await pushWorkspaceChangesToCloud(signature, { forceAllAiProfiles: true, repairMode: true });
105
+ return;
106
+ }
107
+ await pullWorkspaceChangesFromCloud({ repairMode: true });
108
+ }
109
+ finally {
110
+ workspaceRepairModeRef.current = false;
111
+ releaseWorkspaceSyncLease(currentWorkspaceId);
112
+ }
113
+ };
114
+ return {
115
+ retryWorkspaceCloudSync,
116
+ resetWorkspaceSyncCursorAndPull
117
+ };
118
+ }
@@ -0,0 +1,123 @@
1
+ import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
2
+ import { type EnsureWorkspaceReadyResult } from '../../sync/syncService';
3
+ import type { WorkspaceSyncPayload } from '../../sync/workspaceSyncModel';
4
+ import type { WorkspaceSyncPhase } from '../../sync/workspaceSyncState';
5
+ interface CreateWorkspaceTransferCoordinatorArgs {
6
+ cloudAuthConfigured: boolean;
7
+ runtimeMode: 'local' | 'cloud';
8
+ workspaceCloudSyncEnabled: boolean;
9
+ currentWorkspaceId: string;
10
+ workspaceSyncPhase: WorkspaceSyncPhase;
11
+ taxonomyStateFingerprint: string;
12
+ isAuthenticated: boolean;
13
+ checkAuthSession: () => Promise<boolean>;
14
+ resolveCloudAuthUrl: (path: string) => string;
15
+ ensureCloudWorkspaceReadyForSync: () => Promise<EnsureWorkspaceReadyResult>;
16
+ ensureWorkspaceSyncReady: () => Promise<boolean>;
17
+ handleSyncAuthFailure: (source: 'push' | 'pull' | 'apply' | 'handshake', statusCode: number) => Promise<void>;
18
+ clearWorkspaceRetry: () => void;
19
+ clearWorkspaceIssue: () => void;
20
+ isWorkspaceRetryPending: () => boolean;
21
+ scheduleWorkspaceSyncRetry: (minDelayMs?: number) => void;
22
+ persistWorkspaceSyncPatchSafely: (patch: {
23
+ phase: 'error';
24
+ lastErrorMessage: string;
25
+ } | {
26
+ phase: 'active';
27
+ lastPushAt?: string;
28
+ lastPullAt?: string;
29
+ lastSyncedAt: string;
30
+ pullCursor?: string | null;
31
+ lastErrorMessage: null;
32
+ }) => void;
33
+ persistWorkspaceSyncPatchBestEffort: (patch: {
34
+ phase: 'active';
35
+ pullCursor: string | null;
36
+ lastPullAt: string;
37
+ lastSyncedAt: string;
38
+ lastErrorMessage: null;
39
+ }) => Promise<unknown>;
40
+ reportSyncEvent: (workspaceId: string, event: {
41
+ eventType: 'pull' | 'handshake' | 'bootstrap' | 'apply' | 'push';
42
+ status: 'success' | 'error';
43
+ statusCode?: number;
44
+ errorMessage?: string;
45
+ changeCount?: number;
46
+ requestMs?: number;
47
+ details?: Record<string, unknown>;
48
+ }) => void;
49
+ acquireWorkspaceSyncLease: (workspaceId: string, owner: 'pull' | 'push' | 'repair') => Promise<boolean>;
50
+ releaseWorkspaceSyncLease: (workspaceId: string) => void;
51
+ reportWorkspaceWindowContention: (operation: 'pull' | 'push' | 'repair') => void;
52
+ refreshWorkspaceSyncMarkdownDocumentsSnapshot: () => Promise<void>;
53
+ refreshWorkspaceSyncAiProfilesSnapshot: () => Promise<void>;
54
+ refreshWorkspaceSyncAssetsSnapshot: () => Promise<void>;
55
+ refreshWorkspaceSyncDocumentReviewSessionsSnapshot: () => Promise<void>;
56
+ refreshWorkspaceSyncAnnotatedAttachmentSessionsSnapshot: () => Promise<void>;
57
+ refreshLocalWorkspaceTaskCollections: () => Promise<void>;
58
+ buildWorkspaceSyncPayload: (options?: {
59
+ forceAllAiProfiles?: boolean;
60
+ }) => WorkspaceSyncPayload;
61
+ buildWorkspaceSyncSignature: () => string;
62
+ seedWorkspaceSnapshotPushBaseline: () => void;
63
+ shouldSuppressAttachBootstrapPush: (signature: string) => boolean;
64
+ recordSuppressedEventIds: (eventIds: Iterable<string>, options?: {
65
+ queueRef?: MutableRefObject<string[]>;
66
+ maxQueueSize?: number;
67
+ ttlMs?: number;
68
+ }) => void;
69
+ workspaceRepairModeRef: MutableRefObject<boolean>;
70
+ workspaceForceFullAiProfilePushRef: MutableRefObject<boolean>;
71
+ workspacePushInFlightRef: MutableRefObject<boolean>;
72
+ workspacePullInFlightRef: MutableRefObject<boolean>;
73
+ workspaceLastPushedSignatureRef: MutableRefObject<string>;
74
+ workspacePendingSignatureRef: MutableRefObject<string>;
75
+ workspaceLastPushedTaskIdsRef: MutableRefObject<Set<string>>;
76
+ workspaceDeletedTaskIdsRef: MutableRefObject<Set<string>>;
77
+ workspaceDeletedTaskWatermarksRef: MutableRefObject<Map<string, string>>;
78
+ workspacePullCursorRef: MutableRefObject<string | null>;
79
+ workspaceLastPushedWatermarksRef: MutableRefObject<Map<string, string>>;
80
+ workspaceLastPushedInitiativeIdsRef: MutableRefObject<Set<string>>;
81
+ workspaceLastPushedInitiativeWatermarksRef: MutableRefObject<Map<string, string>>;
82
+ workspaceLastPushedWorkstreamIdsRef: MutableRefObject<Set<string>>;
83
+ workspaceLastPushedWorkstreamWatermarksRef: MutableRefObject<Map<string, string>>;
84
+ workspaceLastPushedAiProfileIdsRef: MutableRefObject<Set<string>>;
85
+ workspaceLastPushedAiProfileWatermarksRef: MutableRefObject<Map<string, string>>;
86
+ workspaceLastPushedDocumentPathsRef: MutableRefObject<Set<string>>;
87
+ workspaceLastPushedDocumentWatermarksRef: MutableRefObject<Map<string, string>>;
88
+ workspaceLastPushedAssetPathsRef: MutableRefObject<Set<string>>;
89
+ workspaceLastPushedAssetWatermarksRef: MutableRefObject<Map<string, string>>;
90
+ workspaceLastPushedDocumentReviewSessionIdsRef: MutableRefObject<Set<string>>;
91
+ workspaceLastPushedDocumentReviewSessionWatermarksRef: MutableRefObject<Map<string, string>>;
92
+ workspaceLastPushedDocumentReviewCommentIdsRef: MutableRefObject<Set<string>>;
93
+ workspaceLastPushedDocumentReviewCommentWatermarksRef: MutableRefObject<Map<string, string>>;
94
+ workspaceLastPushedAnnotatedAttachmentSessionIdsRef: MutableRefObject<Set<string>>;
95
+ workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef: MutableRefObject<Map<string, string>>;
96
+ workspaceLastPushedTaskEventWatermarksRef: MutableRefObject<Map<string, string>>;
97
+ workspaceCaptureAttachBootstrapBaselineRef: MutableRefObject<boolean>;
98
+ workspaceStartupFullReconcileRanRef: MutableRefObject<boolean>;
99
+ workspaceFullReconcileInFlightRef: MutableRefObject<boolean>;
100
+ bootstrapLastProgressAtRef: MutableRefObject<number | null>;
101
+ realtimeSuppressedEventQueueRef: MutableRefObject<string[]>;
102
+ setWorkspaceSyncBusy: Dispatch<SetStateAction<boolean>>;
103
+ setUserGlobalSyncStatus: Dispatch<SetStateAction<'disconnected' | 'idle' | 'syncing' | 'error'>>;
104
+ setUserGlobalSyncError: Dispatch<SetStateAction<string | null>>;
105
+ setWorkspaceLastErrorMessage: Dispatch<SetStateAction<string | null>>;
106
+ setWorkspaceLastErrorAt: Dispatch<SetStateAction<string | null>>;
107
+ setWorkspaceLastPullAt: Dispatch<SetStateAction<string | null>>;
108
+ setWorkspaceLastPushAt: Dispatch<SetStateAction<string | null>>;
109
+ setWorkspaceSyncPendingChanges: Dispatch<SetStateAction<number>>;
110
+ setTasks: Dispatch<SetStateAction<any[]>>;
111
+ setArchivedTasks: Dispatch<SetStateAction<any[]>>;
112
+ }
113
+ export declare function createWorkspaceTransferCoordinator({ cloudAuthConfigured, runtimeMode, workspaceCloudSyncEnabled, currentWorkspaceId, workspaceSyncPhase, taxonomyStateFingerprint, isAuthenticated, checkAuthSession, resolveCloudAuthUrl, ensureCloudWorkspaceReadyForSync, ensureWorkspaceSyncReady, handleSyncAuthFailure, clearWorkspaceRetry, clearWorkspaceIssue, isWorkspaceRetryPending, scheduleWorkspaceSyncRetry, persistWorkspaceSyncPatchSafely, persistWorkspaceSyncPatchBestEffort, reportSyncEvent, acquireWorkspaceSyncLease, releaseWorkspaceSyncLease, reportWorkspaceWindowContention, refreshWorkspaceSyncMarkdownDocumentsSnapshot, refreshWorkspaceSyncAiProfilesSnapshot, refreshWorkspaceSyncAssetsSnapshot, refreshWorkspaceSyncDocumentReviewSessionsSnapshot, refreshWorkspaceSyncAnnotatedAttachmentSessionsSnapshot, refreshLocalWorkspaceTaskCollections, buildWorkspaceSyncPayload, buildWorkspaceSyncSignature, seedWorkspaceSnapshotPushBaseline, shouldSuppressAttachBootstrapPush, recordSuppressedEventIds, workspaceRepairModeRef, workspaceForceFullAiProfilePushRef, workspacePushInFlightRef, workspacePullInFlightRef, workspaceLastPushedSignatureRef, workspacePendingSignatureRef, workspaceLastPushedTaskIdsRef, workspaceDeletedTaskIdsRef, workspaceDeletedTaskWatermarksRef, workspacePullCursorRef, workspaceLastPushedWatermarksRef, workspaceLastPushedInitiativeIdsRef, workspaceLastPushedInitiativeWatermarksRef, workspaceLastPushedWorkstreamIdsRef, workspaceLastPushedWorkstreamWatermarksRef, workspaceLastPushedAiProfileIdsRef, workspaceLastPushedAiProfileWatermarksRef, workspaceLastPushedDocumentPathsRef, workspaceLastPushedDocumentWatermarksRef, workspaceLastPushedAssetPathsRef, workspaceLastPushedAssetWatermarksRef, workspaceLastPushedDocumentReviewSessionIdsRef, workspaceLastPushedDocumentReviewSessionWatermarksRef, workspaceLastPushedDocumentReviewCommentIdsRef, workspaceLastPushedDocumentReviewCommentWatermarksRef, workspaceLastPushedAnnotatedAttachmentSessionIdsRef, workspaceLastPushedAnnotatedAttachmentSessionWatermarksRef, workspaceLastPushedTaskEventWatermarksRef, workspaceCaptureAttachBootstrapBaselineRef, workspaceStartupFullReconcileRanRef, workspaceFullReconcileInFlightRef, bootstrapLastProgressAtRef, realtimeSuppressedEventQueueRef, setWorkspaceSyncBusy, setUserGlobalSyncStatus, setUserGlobalSyncError, setWorkspaceLastErrorMessage, setWorkspaceLastErrorAt, setWorkspaceLastPullAt, setWorkspaceLastPushAt, setWorkspaceSyncPendingChanges, setTasks, setArchivedTasks }: CreateWorkspaceTransferCoordinatorArgs): {
114
+ pushWorkspaceChangesToCloud: (signature: string, options?: {
115
+ forceAllAiProfiles?: boolean;
116
+ repairMode?: boolean;
117
+ }) => Promise<boolean>;
118
+ pullWorkspaceChangesFromCloud: (options?: {
119
+ repairMode?: boolean;
120
+ forceCursorNull?: boolean;
121
+ }) => Promise<boolean>;
122
+ };
123
+ export {};