@taskforcehq/taskforce 0.3.301 → 0.3.302

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 (147) hide show
  1. package/dist/Taskforce.module.css +26 -2
  2. package/dist/TaskforceCore.filter-persistence.test.js +1 -1
  3. package/dist/TaskforceCore.js +13 -24
  4. package/dist/TaskforceCore.test.js +167 -152
  5. package/dist/components/features/TaskSettings.js +14 -82
  6. package/dist/components/features/TaskSettings.test.js +33 -70
  7. package/dist/components/features/settings/TaxonomyLibraryManager.js +8 -2
  8. package/dist/components/features/settings/TaxonomyLibraryManager.test.js +1 -1
  9. package/dist/components/task/TaskActionHeader.js +6 -3
  10. package/dist/components/task/TaskCard.js +6 -3
  11. package/dist/components/task/TaskForm.js +2 -2
  12. package/dist/components/task/TaskForm.test.js +41 -2
  13. package/dist/components/ui/ReferenceBadgeButton.js +1 -1
  14. package/dist/components/views/PlansPage.js +9 -8
  15. package/dist/components/views/StandaloneLayout.js +466 -204
  16. package/dist/components/views/panels/PlanningDrawer.js +18 -1
  17. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +43 -0
  18. package/dist/components/views/standalone/modals/AccountHubModal.js +22 -0
  19. package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.d.ts +9 -0
  20. package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.js +8 -0
  21. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +26 -0
  22. package/dist/components/views/standalone/modals/EditProfileModal.js +10 -0
  23. package/dist/components/views/standalone/modals/HelpModal.d.ts +9 -0
  24. package/dist/components/views/standalone/modals/HelpModal.js +8 -0
  25. package/dist/components/views/standalone/modals/ScheduleWarningModal.d.ts +13 -0
  26. package/dist/components/views/standalone/modals/ScheduleWarningModal.js +6 -0
  27. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +61 -0
  28. package/dist/components/views/standalone/modals/SyncStatusModal.js +38 -0
  29. package/dist/components/views/standalone/modals/TeamManagementModal.d.ts +64 -0
  30. package/dist/components/views/standalone/modals/TeamManagementModal.js +10 -0
  31. package/dist/components/views/standalone/modals/types.d.ts +2 -0
  32. package/dist/components/views/standalone/modals/types.js +1 -0
  33. package/dist/components/views/teamManagementAccess.d.ts +1 -1
  34. package/dist/components/views/teamManagementAccess.js +2 -2
  35. package/dist/components/views/teamManagementAccess.test.js +3 -3
  36. package/dist/config/deployment.js +2 -2
  37. package/dist/config/deployment.test.js +5 -3
  38. package/dist/core/AiProfileService.js +7 -2
  39. package/dist/core/AiProfiles.test.js +19 -0
  40. package/dist/core/SyncReconciliationService.d.ts +2 -0
  41. package/dist/core/SyncReconciliationService.js +3 -0
  42. package/dist/core/TaskAuditTimeline.test.js +40 -0
  43. package/dist/core/Taskforce.d.ts +49 -0
  44. package/dist/core/Taskforce.ids.test.js +133 -0
  45. package/dist/core/Taskforce.js +241 -78
  46. package/dist/core/UserProfileAvatarDrafts.test.d.ts +1 -0
  47. package/dist/core/UserProfileAvatarDrafts.test.js +102 -0
  48. package/dist/core/taskReferencePolicy.d.ts +28 -0
  49. package/dist/core/taskReferencePolicy.js +189 -0
  50. package/dist/core/types.d.ts +2 -0
  51. package/dist/hooks/tasks/useTaskFormActions.js +3 -0
  52. package/dist/hooks/useTaskData.js +3 -2
  53. package/dist/hooks/useTaskData.test.js +66 -0
  54. package/dist/hooks/useTaskforce.d.ts +5 -0
  55. package/dist/hooks/useTaskforce.js +63 -15
  56. package/dist/hooks/useTaskforce.sync-behavior.test.js +185 -6
  57. package/dist/mcp/aiProfileBootstrap.d.ts +29 -0
  58. package/dist/mcp/aiProfileBootstrap.js +80 -0
  59. package/dist/mcp/aiProfileBootstrap.test.d.ts +1 -0
  60. package/dist/mcp/aiProfileBootstrap.test.js +68 -0
  61. package/dist/mcp/clientIntegrations.d.ts +2 -8
  62. package/dist/mcp/clientIntegrations.js +21 -40
  63. package/dist/mcp/clientIntegrations.test.js +28 -2
  64. package/dist/mcp/clientProfileDefaults.d.ts +12 -0
  65. package/dist/mcp/clientProfileDefaults.js +37 -0
  66. package/dist/mcp/runtime.d.ts +10 -7
  67. package/dist/mcp/runtime.js +41 -19
  68. package/dist/mcp/runtime.test.js +49 -2
  69. package/dist/migrations/taskSchemaMigrations.js +53 -1
  70. package/dist/qaOpen.test.d.ts +1 -0
  71. package/dist/qaOpen.test.js +56 -0
  72. package/dist/server/index.cookieProxy.test.js +1 -0
  73. package/dist/server/index.d.ts +1 -0
  74. package/dist/server/index.js +15 -1
  75. package/dist/server/index.test.js +14 -1
  76. package/dist/server/routes/admin.js +25 -22
  77. package/dist/server/routes/auth.d.ts +5 -0
  78. package/dist/server/routes/auth.js +350 -16
  79. package/dist/server/routes/billing.js +11 -1
  80. package/dist/server/routes/billing.test.js +32 -2
  81. package/dist/server/routes/documents.js +6 -1
  82. package/dist/server/routes/shared.d.ts +1 -1
  83. package/dist/server/routes/shared.js +11 -3
  84. package/dist/server/routes/sync.integration.test.js +130 -0
  85. package/dist/server/routes/sync.js +226 -1924
  86. package/dist/server/routes/tasks.js +18 -4
  87. package/dist/server/routes.js +26 -19
  88. package/dist/server/routes.test.js +352 -6
  89. package/dist/shared/runtimeContract.d.ts +1 -1
  90. package/dist/sync/collaborationSyncPayload.d.ts +17 -0
  91. package/dist/sync/collaborationSyncPayload.js +131 -0
  92. package/dist/sync/collaborationSyncPayload.test.d.ts +1 -0
  93. package/dist/sync/collaborationSyncPayload.test.js +104 -0
  94. package/dist/sync/collaborationSyncState.d.ts +15 -0
  95. package/dist/sync/collaborationSyncState.js +60 -0
  96. package/dist/sync/contentSyncPayload.d.ts +45 -0
  97. package/dist/sync/contentSyncPayload.js +104 -0
  98. package/dist/sync/contentSyncPayload.test.d.ts +1 -0
  99. package/dist/sync/contentSyncPayload.test.js +104 -0
  100. package/dist/sync/contentSyncState.d.ts +88 -0
  101. package/dist/sync/contentSyncState.js +743 -0
  102. package/dist/sync/planningSyncPayload.d.ts +9 -0
  103. package/dist/sync/planningSyncPayload.js +82 -0
  104. package/dist/sync/planningSyncPayload.test.d.ts +1 -0
  105. package/dist/sync/planningSyncPayload.test.js +68 -0
  106. package/dist/sync/syncApplyHandlers.d.ts +83 -0
  107. package/dist/sync/syncApplyHandlers.js +445 -0
  108. package/dist/sync/taskSyncPayload.d.ts +33 -0
  109. package/dist/sync/taskSyncPayload.js +126 -0
  110. package/dist/sync/taskSyncPayload.test.d.ts +1 -0
  111. package/dist/sync/taskSyncPayload.test.js +54 -0
  112. package/dist/sync/workspacePullFeed.d.ts +28 -0
  113. package/dist/sync/workspacePullFeed.js +301 -0
  114. package/dist/sync/workspacePullFeed.test.d.ts +1 -0
  115. package/dist/sync/workspacePullFeed.test.js +166 -0
  116. package/dist/sync/workspaceSyncModel.d.ts +4 -1
  117. package/dist/sync/workspaceSyncModel.js +9 -2
  118. package/dist/sync/workspaceSyncModel.test.js +29 -0
  119. package/dist/test/setup.js +1 -1
  120. package/dist/types.d.ts +1 -0
  121. package/dist/ui/assets/{AgentsModule-Bdq3T1Ts.js → AgentsModule-JG5jc3he.js} +1 -1
  122. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-jKUVo-PJ.js → AnnotatedAttachmentWorkspace-Dvi02Y7q.js} +1 -1
  123. package/dist/ui/assets/{DocumentWorkspace-DuQa-uIC.js → DocumentWorkspace-iys3zfca.js} +2 -2
  124. package/dist/ui/assets/{InitiativesModule-C8Pi2VTk.js → InitiativesModule-DJvLJI3A.js} +1 -1
  125. package/dist/ui/assets/PlansPage-BMPlpFpw.js +1 -0
  126. package/dist/ui/assets/TaskSettings-Bqd4cCzW.js +8 -0
  127. package/dist/ui/assets/{TaskSettings-BwB9NtmJ.css → TaskSettings-CnIBL_Eb.css} +1 -1
  128. package/dist/ui/assets/{WorkflowsModule-b6TLuHwJ.js → WorkflowsModule-BguHeQaV.js} +1 -1
  129. package/dist/ui/assets/index-MXeWoebC.css +1 -0
  130. package/dist/ui/assets/index-YJ4k5QNa.js +6 -0
  131. package/dist/ui/assets/{vendor-icons-QZyhEwgT.js → vendor-icons-C8EED3Oh.js} +1 -1
  132. package/dist/ui/index.html +3 -3
  133. package/dist/utils/billingStatusCache.d.ts +21 -0
  134. package/dist/utils/billingStatusCache.js +70 -0
  135. package/dist/utils/taskActivity.js +17 -4
  136. package/dist/utils/taskActivity.test.js +27 -0
  137. package/dist/utils/taskNormalization.js +10 -2
  138. package/dist/utils/taskReferences.d.ts +11 -1
  139. package/dist/utils/taskReferences.js +33 -1
  140. package/package.json +2 -1
  141. package/scripts/qa-open-lib.mjs +175 -0
  142. package/scripts/qa-open-lib.mjs.d.ts +49 -0
  143. package/scripts/qa-open.mjs +352 -0
  144. package/dist/ui/assets/PlansPage-B6BDECSi.js +0 -1
  145. package/dist/ui/assets/TaskSettings-DUJgRTPU.js +0 -8
  146. package/dist/ui/assets/index-BiiF1cLQ.css +0 -1
  147. package/dist/ui/assets/index-xBWLPOEb.js +0 -6
@@ -0,0 +1,9 @@
1
+ import type { WorkspaceSyncInitiativeSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
2
+ import type { WorkspaceTaxonomyState } from '../shared/taxonomyState.js';
3
+ export declare function normalizeTaxonomySyncPayload(raw: unknown): {
4
+ taxonomies?: unknown[];
5
+ taxonomyState?: WorkspaceTaxonomyState;
6
+ updatedAt: string;
7
+ } | null;
8
+ export declare function normalizeInitiativeSyncPayload(raw: unknown, sourceWatermark?: string): WorkspaceSyncInitiativeSnapshot | null;
9
+ export declare function normalizeWorkstreamSyncPayload(raw: unknown, sourceWatermark?: string): WorkspaceSyncWorkstreamSnapshot | null;
@@ -0,0 +1,82 @@
1
+ function toOptionalTrimmedString(value) {
2
+ if (typeof value !== 'string')
3
+ return undefined;
4
+ const normalized = value.trim();
5
+ return normalized.length > 0 ? normalized : undefined;
6
+ }
7
+ function toNullableTrimmedString(value) {
8
+ return toOptionalTrimmedString(value) ?? null;
9
+ }
10
+ function toOptionalPositiveInteger(value) {
11
+ if (value === undefined || value === null || value === '')
12
+ return null;
13
+ const normalized = typeof value === 'number' ? value : Number(value);
14
+ if (!Number.isFinite(normalized))
15
+ return null;
16
+ return Math.max(1, Math.floor(normalized));
17
+ }
18
+ function toOptionalInteger(value) {
19
+ if (value === undefined || value === null || value === '')
20
+ return null;
21
+ const normalized = typeof value === 'number' ? value : Number(value);
22
+ if (!Number.isFinite(normalized))
23
+ return null;
24
+ return Math.floor(normalized);
25
+ }
26
+ export function normalizeTaxonomySyncPayload(raw) {
27
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
28
+ return null;
29
+ const source = raw;
30
+ const taxonomyState = source.taxonomyState && typeof source.taxonomyState === 'object' && !Array.isArray(source.taxonomyState)
31
+ ? source.taxonomyState
32
+ : undefined;
33
+ const taxonomies = Array.isArray(source.taxonomies) ? source.taxonomies : undefined;
34
+ if (!taxonomyState && !taxonomies)
35
+ return null;
36
+ return {
37
+ ...(taxonomies ? { taxonomies } : {}),
38
+ ...(taxonomyState ? { taxonomyState } : {}),
39
+ updatedAt: String(source.updatedAt || source.watermark || '').trim(),
40
+ };
41
+ }
42
+ export function normalizeInitiativeSyncPayload(raw, sourceWatermark) {
43
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
44
+ return null;
45
+ const source = raw;
46
+ const id = String(source.id || '').trim();
47
+ if (!id)
48
+ return null;
49
+ return {
50
+ id,
51
+ referenceNumber: toOptionalPositiveInteger(source.referenceNumber),
52
+ referenceLabel: toOptionalTrimmedString(source.referenceLabel),
53
+ title: String(source.title || '').trim(),
54
+ description: typeof source.description === 'string' ? source.description : null,
55
+ ownerId: toNullableTrimmedString(source.ownerId),
56
+ createdAt: String(source.createdAt || sourceWatermark || '').trim(),
57
+ updatedAt: String(source.updatedAt || sourceWatermark || source.createdAt || '').trim(),
58
+ order: toOptionalInteger(source.order),
59
+ isArchived: Boolean(source.isArchived),
60
+ };
61
+ }
62
+ export function normalizeWorkstreamSyncPayload(raw, sourceWatermark) {
63
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
64
+ return null;
65
+ const source = raw;
66
+ const id = String(source.id || '').trim();
67
+ if (!id)
68
+ return null;
69
+ return {
70
+ id,
71
+ referenceNumber: toOptionalPositiveInteger(source.referenceNumber),
72
+ referenceLabel: toOptionalTrimmedString(source.referenceLabel),
73
+ initiativeId: toNullableTrimmedString(source.initiativeId),
74
+ title: String(source.title || '').trim(),
75
+ description: typeof source.description === 'string' ? source.description : null,
76
+ ownerId: toNullableTrimmedString(source.ownerId),
77
+ createdAt: String(source.createdAt || sourceWatermark || '').trim(),
78
+ updatedAt: String(source.updatedAt || sourceWatermark || source.createdAt || '').trim(),
79
+ order: toOptionalInteger(source.order),
80
+ isArchived: Boolean(source.isArchived),
81
+ };
82
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { normalizeInitiativeSyncPayload, normalizeTaxonomySyncPayload, normalizeWorkstreamSyncPayload, } from './planningSyncPayload';
3
+ describe('planningSyncPayload', () => {
4
+ it('normalizes taxonomy sync payloads', () => {
5
+ const payload = normalizeTaxonomySyncPayload({
6
+ taxonomies: [{ id: 'priority' }],
7
+ updatedAt: '2026-04-10T10:00:00.000Z',
8
+ });
9
+ expect(payload).toEqual({
10
+ taxonomies: [{ id: 'priority' }],
11
+ updatedAt: '2026-04-10T10:00:00.000Z',
12
+ });
13
+ });
14
+ it('normalizes initiative sync payloads', () => {
15
+ const initiative = normalizeInitiativeSyncPayload({
16
+ id: 'initiative-1',
17
+ referenceNumber: '4',
18
+ referenceLabel: ' IN-4 ',
19
+ title: ' Launch ',
20
+ description: ' Ship it ',
21
+ ownerId: ' owner-1 ',
22
+ createdAt: '2026-04-10T10:00:00.000Z',
23
+ updatedAt: '2026-04-10T11:00:00.000Z',
24
+ order: '2',
25
+ isArchived: true,
26
+ });
27
+ expect(initiative).toEqual({
28
+ id: 'initiative-1',
29
+ referenceNumber: 4,
30
+ referenceLabel: 'IN-4',
31
+ title: 'Launch',
32
+ description: ' Ship it ',
33
+ ownerId: 'owner-1',
34
+ createdAt: '2026-04-10T10:00:00.000Z',
35
+ updatedAt: '2026-04-10T11:00:00.000Z',
36
+ order: 2,
37
+ isArchived: true,
38
+ });
39
+ });
40
+ it('normalizes workstream sync payloads', () => {
41
+ const workstream = normalizeWorkstreamSyncPayload({
42
+ id: 'workstream-1',
43
+ referenceNumber: '2',
44
+ referenceLabel: ' WS-2 ',
45
+ initiativeId: ' initiative-1 ',
46
+ title: ' Backend ',
47
+ description: ' API work ',
48
+ ownerId: ' owner-2 ',
49
+ createdAt: '2026-04-10T10:00:00.000Z',
50
+ updatedAt: '2026-04-10T11:00:00.000Z',
51
+ order: '5',
52
+ isArchived: false,
53
+ });
54
+ expect(workstream).toEqual({
55
+ id: 'workstream-1',
56
+ referenceNumber: 2,
57
+ referenceLabel: 'WS-2',
58
+ initiativeId: 'initiative-1',
59
+ title: 'Backend',
60
+ description: ' API work ',
61
+ ownerId: 'owner-2',
62
+ createdAt: '2026-04-10T10:00:00.000Z',
63
+ updatedAt: '2026-04-10T11:00:00.000Z',
64
+ order: 5,
65
+ isArchived: false,
66
+ });
67
+ });
68
+ });
@@ -0,0 +1,83 @@
1
+ import type { TaskforceCore, TaskforceSyncCapable } from '../core/Taskforce.js';
2
+ import type { WorkspaceSyncAiProfileSnapshot, WorkspaceSyncAnnotatedAttachmentSessionSnapshot, WorkspaceSyncDocumentReviewCommentSnapshot, WorkspaceSyncDocumentReviewSessionSnapshot, WorkspaceSyncInitiativeSnapshot, WorkspaceSyncWorkspaceMemberSnapshot, WorkspaceSyncWorkstreamSnapshot } from './workspaceSyncModel.js';
3
+ import type { BinaryAssetSyncPayload, DocumentSyncPayload } from './contentSyncPayload.js';
4
+ type SyncCore = TaskforceCore & TaskforceSyncCapable;
5
+ type SyncRouteError = Error & {
6
+ code?: string;
7
+ statusCode?: number;
8
+ details?: Record<string, unknown>;
9
+ };
10
+ type RecordSyncDiagnostic = (workspaceId: string, eventType: 'pull' | 'push' | 'apply', errorMessage: string, details?: Record<string, unknown>) => void;
11
+ type CreateSyncRouteError = (message: string, details: Record<string, unknown>, options?: {
12
+ code?: string;
13
+ statusCode?: number;
14
+ }) => SyncRouteError;
15
+ export declare function resolveSyncConflictOrdering(incomingWatermark: string, existingWatermark: string, incomingTieBreak: string, existingTieBreak: string): number;
16
+ export declare function applyPlanningSyncChanges(input: {
17
+ core: SyncCore;
18
+ workspaceId: string;
19
+ incomingInitiatives: Map<string, WorkspaceSyncInitiativeSnapshot>;
20
+ incomingWorkstreams: Map<string, WorkspaceSyncWorkstreamSnapshot>;
21
+ incomingTaxonomies: unknown[] | null;
22
+ incomingTaxonomyState: Record<string, unknown> | null;
23
+ incomingTaxonomiesUpdatedAt: string;
24
+ workspaceTaxonomySyncMeta: Map<string, {
25
+ updatedAt: string;
26
+ hash: string;
27
+ }>;
28
+ recordSyncDiagnostic: RecordSyncDiagnostic;
29
+ }): void;
30
+ export declare function applyAiProfileAndMemberSyncChanges(input: {
31
+ core: SyncCore;
32
+ workspaceId: string;
33
+ incomingAiProfiles: Map<string, WorkspaceSyncAiProfileSnapshot>;
34
+ workspaceMembers?: WorkspaceSyncWorkspaceMemberSnapshot[];
35
+ recordSyncDiagnostic: RecordSyncDiagnostic;
36
+ assertSyncedAiProfilesPersisted: (workspaceId: string, incomingAiProfiles: Map<string, WorkspaceSyncAiProfileSnapshot>) => void;
37
+ createSyncRouteError: CreateSyncRouteError;
38
+ }): void;
39
+ export declare function applyContentSyncChanges(input: {
40
+ core: SyncCore;
41
+ workspaceId: string;
42
+ incomingDocuments: DocumentSyncPayload[];
43
+ incomingDocumentDeletes: Map<string, string>;
44
+ incomingAssets: BinaryAssetSyncPayload[];
45
+ incomingAssetDeletes: Map<string, string>;
46
+ basePath: string;
47
+ hasObjectStorageClient: () => boolean;
48
+ hasDocumentSyncMetadataDrift: (workspaceId: string, doc: DocumentSyncPayload, options?: {
49
+ allowReferenceNumberReassignment?: boolean;
50
+ }) => boolean;
51
+ hasBinaryAssetSyncMetadataDrift: (workspaceId: string, asset: BinaryAssetSyncPayload, options?: {
52
+ allowReferenceNumberReassignment?: boolean;
53
+ }) => boolean;
54
+ writeWorkspaceSyncDocument: (basePath: string, doc: DocumentSyncPayload, workspaceId?: string, options?: {
55
+ allowReferenceNumberReassignment?: boolean;
56
+ }) => Promise<void>;
57
+ deleteWorkspaceSyncDocument: (basePath: string, docPath: string, workspaceId?: string) => void;
58
+ writeWorkspaceSyncBinaryAsset: (basePath: string, asset: BinaryAssetSyncPayload, workspaceId?: string, options?: {
59
+ allowReferenceNumberReassignment?: boolean;
60
+ }) => Promise<void>;
61
+ deleteWorkspaceSyncBinaryAsset: (basePath: string, assetPath: string, workspaceId?: string) => void;
62
+ getExistingBinaryAsset: (assetPath: string, workspaceId: string) => {
63
+ updatedAt?: string | null;
64
+ contentSha256?: string | null;
65
+ } | null;
66
+ recordSyncDiagnostic: RecordSyncDiagnostic;
67
+ options?: {
68
+ allowReferenceNumberReassignment?: boolean;
69
+ };
70
+ }): Promise<void>;
71
+ export declare function applyCollaborationSyncChanges(input: {
72
+ core: SyncCore;
73
+ workspaceId: string;
74
+ incomingDocumentReviewSessions: Map<string, WorkspaceSyncDocumentReviewSessionSnapshot>;
75
+ incomingDocumentReviewSessionDeletes: Map<string, string>;
76
+ incomingDocumentReviewComments: Map<string, WorkspaceSyncDocumentReviewCommentSnapshot>;
77
+ incomingDocumentReviewCommentDeletes: Map<string, string>;
78
+ incomingAnnotatedAttachmentSessions: Map<string, WorkspaceSyncAnnotatedAttachmentSessionSnapshot>;
79
+ incomingAnnotatedAttachmentSessionDeletes: Map<string, string>;
80
+ recordSyncDiagnostic: RecordSyncDiagnostic;
81
+ createSyncRouteError: CreateSyncRouteError;
82
+ }): void;
83
+ export {};