@taskforcehq/taskforce 0.3.301 → 0.3.303

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 (171) hide show
  1. package/dist/Taskforce.module.css +37 -2
  2. package/dist/TaskforceCore.filter-persistence.test.js +1 -1
  3. package/dist/TaskforceCore.js +72 -33
  4. package/dist/TaskforceCore.test.js +848 -130
  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/task/TaskKanban.test.js +17 -0
  14. package/dist/components/ui/ReferenceBadgeButton.js +1 -1
  15. package/dist/components/views/PlansPage.d.ts +3 -1
  16. package/dist/components/views/PlansPage.js +109 -49
  17. package/dist/components/views/PlansPage.test.d.ts +1 -0
  18. package/dist/components/views/PlansPage.test.js +100 -0
  19. package/dist/components/views/StandaloneLayout.d.ts +1 -0
  20. package/dist/components/views/StandaloneLayout.js +473 -256
  21. package/dist/components/views/panels/PlanningDrawer.js +18 -1
  22. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +48 -0
  23. package/dist/components/views/standalone/modals/AccountHubModal.js +36 -0
  24. package/dist/components/views/standalone/modals/AccountHubModal.test.d.ts +1 -0
  25. package/dist/components/views/standalone/modals/AccountHubModal.test.js +26 -0
  26. package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.d.ts +9 -0
  27. package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.js +8 -0
  28. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +26 -0
  29. package/dist/components/views/standalone/modals/EditProfileModal.js +10 -0
  30. package/dist/components/views/standalone/modals/HelpModal.d.ts +9 -0
  31. package/dist/components/views/standalone/modals/HelpModal.js +8 -0
  32. package/dist/components/views/standalone/modals/ScheduleWarningModal.d.ts +13 -0
  33. package/dist/components/views/standalone/modals/ScheduleWarningModal.js +6 -0
  34. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +61 -0
  35. package/dist/components/views/standalone/modals/SyncStatusModal.js +38 -0
  36. package/dist/components/views/standalone/modals/TeamManagementModal.d.ts +64 -0
  37. package/dist/components/views/standalone/modals/TeamManagementModal.js +10 -0
  38. package/dist/components/views/standalone/modals/types.d.ts +2 -0
  39. package/dist/components/views/standalone/modals/types.js +1 -0
  40. package/dist/components/views/teamManagementAccess.d.ts +1 -1
  41. package/dist/components/views/teamManagementAccess.js +2 -2
  42. package/dist/components/views/teamManagementAccess.test.js +3 -3
  43. package/dist/config/deployment.js +2 -2
  44. package/dist/config/deployment.test.js +5 -3
  45. package/dist/core/AiProfileService.js +7 -2
  46. package/dist/core/AiProfiles.test.js +19 -0
  47. package/dist/core/EntitlementsPolicy.test.js +2 -2
  48. package/dist/core/GlobalSettingsService.js +78 -18
  49. package/dist/core/PlanEntitlementService.d.ts +29 -5
  50. package/dist/core/PlanEntitlementService.js +297 -219
  51. package/dist/core/SignupMonetizationSettings.test.js +173 -49
  52. package/dist/core/SyncReconciliationService.d.ts +2 -0
  53. package/dist/core/SyncReconciliationService.js +3 -0
  54. package/dist/core/SystemAdmin.test.js +186 -96
  55. package/dist/core/TaskAuditTimeline.test.js +40 -0
  56. package/dist/core/Taskforce.d.ts +100 -10
  57. package/dist/core/Taskforce.ids.test.js +133 -0
  58. package/dist/core/Taskforce.js +459 -127
  59. package/dist/core/Taskforce.mcpAuth.test.js +0 -2
  60. package/dist/core/UserProfileAvatarDrafts.test.d.ts +1 -0
  61. package/dist/core/UserProfileAvatarDrafts.test.js +111 -0
  62. package/dist/core/taskReferencePolicy.d.ts +28 -0
  63. package/dist/core/taskReferencePolicy.js +189 -0
  64. package/dist/core/types.d.ts +13 -12
  65. package/dist/hooks/tasks/useTaskFormActions.js +3 -0
  66. package/dist/hooks/useSyncOrchestrator.js +17 -3
  67. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +97 -5
  68. package/dist/hooks/useTaskData.js +3 -2
  69. package/dist/hooks/useTaskData.test.js +66 -0
  70. package/dist/hooks/useTaskforce.d.ts +8 -0
  71. package/dist/hooks/useTaskforce.js +72 -19
  72. package/dist/hooks/useTaskforce.sync-behavior.test.js +185 -6
  73. package/dist/mcp/aiProfileBootstrap.d.ts +29 -0
  74. package/dist/mcp/aiProfileBootstrap.js +80 -0
  75. package/dist/mcp/aiProfileBootstrap.test.d.ts +1 -0
  76. package/dist/mcp/aiProfileBootstrap.test.js +68 -0
  77. package/dist/mcp/clientIntegrations.d.ts +2 -8
  78. package/dist/mcp/clientIntegrations.js +21 -40
  79. package/dist/mcp/clientIntegrations.test.js +28 -2
  80. package/dist/mcp/clientProfileDefaults.d.ts +12 -0
  81. package/dist/mcp/clientProfileDefaults.js +37 -0
  82. package/dist/mcp/runtime.d.ts +10 -7
  83. package/dist/mcp/runtime.js +131 -48
  84. package/dist/mcp/runtime.test.js +321 -83
  85. package/dist/migrations/billingSchemaParity.test.js +3 -0
  86. package/dist/migrations/taskSchemaMigrations.js +68 -1
  87. package/dist/qaOpen.test.d.ts +1 -0
  88. package/dist/qaOpen.test.js +56 -0
  89. package/dist/server/index.cookieProxy.test.js +2 -0
  90. package/dist/server/index.d.ts +1 -0
  91. package/dist/server/index.js +17 -1
  92. package/dist/server/index.test.js +15 -1
  93. package/dist/server/mockStripe.d.ts +1 -0
  94. package/dist/server/mockStripe.js +2 -0
  95. package/dist/server/routes/admin.js +105 -45
  96. package/dist/server/routes/auth.d.ts +6 -0
  97. package/dist/server/routes/auth.js +505 -30
  98. package/dist/server/routes/billing.js +517 -24
  99. package/dist/server/routes/billing.test.js +967 -45
  100. package/dist/server/routes/documents.js +6 -1
  101. package/dist/server/routes/shared.d.ts +1 -1
  102. package/dist/server/routes/shared.js +16 -6
  103. package/dist/server/routes/sync.integration.test.js +290 -0
  104. package/dist/server/routes/sync.js +234 -1922
  105. package/dist/server/routes/tasks.js +18 -4
  106. package/dist/server/routes.js +29 -22
  107. package/dist/server/routes.test.js +639 -82
  108. package/dist/shared/runtimeContract.d.ts +1 -1
  109. package/dist/sync/cloudSyncApi.d.ts +1 -0
  110. package/dist/sync/collaborationSyncPayload.d.ts +17 -0
  111. package/dist/sync/collaborationSyncPayload.js +131 -0
  112. package/dist/sync/collaborationSyncPayload.test.d.ts +1 -0
  113. package/dist/sync/collaborationSyncPayload.test.js +104 -0
  114. package/dist/sync/collaborationSyncState.d.ts +15 -0
  115. package/dist/sync/collaborationSyncState.js +60 -0
  116. package/dist/sync/contentSyncPayload.d.ts +45 -0
  117. package/dist/sync/contentSyncPayload.js +104 -0
  118. package/dist/sync/contentSyncPayload.test.d.ts +1 -0
  119. package/dist/sync/contentSyncPayload.test.js +104 -0
  120. package/dist/sync/contentSyncState.d.ts +98 -0
  121. package/dist/sync/contentSyncState.js +1004 -0
  122. package/dist/sync/planningSyncPayload.d.ts +9 -0
  123. package/dist/sync/planningSyncPayload.js +82 -0
  124. package/dist/sync/planningSyncPayload.test.d.ts +1 -0
  125. package/dist/sync/planningSyncPayload.test.js +68 -0
  126. package/dist/sync/syncApplyHandlers.d.ts +83 -0
  127. package/dist/sync/syncApplyHandlers.js +445 -0
  128. package/dist/sync/syncService.d.ts +1 -0
  129. package/dist/sync/syncService.js +21 -8
  130. package/dist/sync/taskSyncPayload.d.ts +33 -0
  131. package/dist/sync/taskSyncPayload.js +126 -0
  132. package/dist/sync/taskSyncPayload.test.d.ts +1 -0
  133. package/dist/sync/taskSyncPayload.test.js +54 -0
  134. package/dist/sync/workspacePullFeed.d.ts +38 -0
  135. package/dist/sync/workspacePullFeed.js +349 -0
  136. package/dist/sync/workspacePullFeed.test.d.ts +1 -0
  137. package/dist/sync/workspacePullFeed.test.js +278 -0
  138. package/dist/sync/workspaceSyncModel.d.ts +4 -1
  139. package/dist/sync/workspaceSyncModel.js +9 -2
  140. package/dist/sync/workspaceSyncModel.test.js +29 -0
  141. package/dist/test/setup.js +1 -1
  142. package/dist/types.d.ts +1 -0
  143. package/dist/ui/assets/{AgentsModule-Bdq3T1Ts.js → AgentsModule-CpsTmrIW.js} +1 -1
  144. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-jKUVo-PJ.js → AnnotatedAttachmentWorkspace-C_TmXZwA.js} +1 -1
  145. package/dist/ui/assets/{DocumentWorkspace-DuQa-uIC.js → DocumentWorkspace-C3GyzrWm.js} +2 -2
  146. package/dist/ui/assets/{InitiativesModule-C8Pi2VTk.js → InitiativesModule-4-Rh2K2n.js} +1 -1
  147. package/dist/ui/assets/PlansPage-BP7AYOqr.js +1 -0
  148. package/dist/ui/assets/TaskSettings-BOC5F6Ag.js +8 -0
  149. package/dist/ui/assets/{TaskSettings-BwB9NtmJ.css → TaskSettings-CnIBL_Eb.css} +1 -1
  150. package/dist/ui/assets/{WorkflowsModule-b6TLuHwJ.js → WorkflowsModule-CGk9s3NJ.js} +1 -1
  151. package/dist/ui/assets/index-CLIMgR6g.js +6 -0
  152. package/dist/ui/assets/index-DneETxcu.css +1 -0
  153. package/dist/ui/assets/{vendor-icons-QZyhEwgT.js → vendor-icons-pWocEipT.js} +1 -1
  154. package/dist/ui/index.html +3 -3
  155. package/dist/utils/accountProfileSummaryCache.d.ts +31 -0
  156. package/dist/utils/accountProfileSummaryCache.js +97 -0
  157. package/dist/utils/accountProfileSummaryCache.test.d.ts +1 -0
  158. package/dist/utils/accountProfileSummaryCache.test.js +63 -0
  159. package/dist/utils/taskActivity.js +17 -4
  160. package/dist/utils/taskActivity.test.js +27 -0
  161. package/dist/utils/taskNormalization.js +10 -2
  162. package/dist/utils/taskReferences.d.ts +11 -1
  163. package/dist/utils/taskReferences.js +33 -1
  164. package/package.json +4 -3
  165. package/scripts/qa-open-lib.mjs +175 -0
  166. package/scripts/qa-open-lib.mjs.d.ts +49 -0
  167. package/scripts/qa-open.mjs +352 -0
  168. package/dist/ui/assets/PlansPage-B6BDECSi.js +0 -1
  169. package/dist/ui/assets/TaskSettings-DUJgRTPU.js +0 -8
  170. package/dist/ui/assets/index-BiiF1cLQ.css +0 -1
  171. package/dist/ui/assets/index-xBWLPOEb.js +0 -6
@@ -58,6 +58,7 @@ import { parseJsonBody } from '../routes.js';
58
58
  import { resolveErrorStatusCode, requestHeader, requestRuntimeMode } from './shared.js';
59
59
  import { listBuiltInCustomTaxonomyLibraryPacks } from '../../shared/customTaxonomyLibrary.js';
60
60
  import { listBuiltInTaxonomyLibraryPacks } from '../../shared/taxonomyLibrary.js';
61
+ import { shouldUseProvisionalTaskReferences } from '../../utils/taskReferences.js';
61
62
  // === SECTION: Registration ===
62
63
  export function registerTaskRoutes(deps) {
63
64
  const { addRoute, core, context, requestWorkspaceId, ensureAppAccess, resolveEffectiveObjectStorageConfig, buildBatchSummary, CLOUD_SAFE_CONFIG_PATHS, } = deps;
@@ -343,7 +344,8 @@ export function registerTaskRoutes(deps) {
343
344
  const result = core.bulkCreateTasks([taskInput], {
344
345
  atomic: true,
345
346
  validateOnly: true,
346
- workspaceId
347
+ workspaceId,
348
+ provisionalLocalReference: shouldUseProvisionalTaskReferences(requestRuntimeMode(req))
347
349
  });
348
350
  const hasErrors = result.errors.length > 0;
349
351
  const failureStatus = hasErrors
@@ -361,7 +363,11 @@ export function registerTaskRoutes(deps) {
361
363
  }
362
364
  try {
363
365
  const workspaceId = requestWorkspaceId(req);
364
- const task = core.createTask(taskInput, { workspaceId, actorRef: 'user' });
366
+ const task = core.createTask(taskInput, {
367
+ workspaceId,
368
+ actorRef: 'user',
369
+ provisionalLocalReference: shouldUseProvisionalTaskReferences(requestRuntimeMode(req))
370
+ });
365
371
  res.writeHead(201, { 'Content-Type': 'application/json' });
366
372
  res.end(JSON.stringify(task));
367
373
  }
@@ -386,7 +392,14 @@ export function registerTaskRoutes(deps) {
386
392
  const body = await parseJsonBody(req);
387
393
  try {
388
394
  const workspaceId = requestWorkspaceId(req);
389
- const updated = core.updateTask(params.id, body, workspaceId, { actorRef: 'user' });
395
+ const saveSource = body?.saveSource === 'autosave' ? 'autosave' : 'manual';
396
+ const updates = body && typeof body === 'object'
397
+ ? Object.fromEntries(Object.entries(body).filter(([key]) => key !== 'saveSource'))
398
+ : body;
399
+ const updated = core.updateTask(params.id, updates, workspaceId, {
400
+ actorRef: 'user',
401
+ skipTaskEvents: saveSource === 'autosave'
402
+ });
390
403
  if (!updated) {
391
404
  res.writeHead(404, { 'Content-Type': 'application/json' });
392
405
  res.end(JSON.stringify({ error: 'Task not found' }));
@@ -869,7 +882,8 @@ export function registerTaskRoutes(deps) {
869
882
  const result = core.bulkCreateTasks(tasks, {
870
883
  atomic: atomic !== false,
871
884
  validateOnly: validate_only === true,
872
- workspaceId
885
+ workspaceId,
886
+ provisionalLocalReference: shouldUseProvisionalTaskReferences(requestRuntimeMode(req))
873
887
  });
874
888
  const hasErrors = result.errors.length > 0;
875
889
  const succeeded = validate_only ? (hasErrors ? 0 : result.total) : result.created.length;
@@ -10,6 +10,7 @@ import { createHash, randomUUID } from 'crypto';
10
10
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
11
11
  import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
12
12
  import { TaskforceRuleError } from '../core/Taskforce.js';
13
+ import { parseAiProfileBootstrapHeaders } from '../mcp/aiProfileBootstrap.js';
13
14
  import { createTaskforceMcpServer, isMcpWriteToolName } from '../mcp/runtime.js';
14
15
  import { applyPrefixedRateLimitHeaders } from './rateLimit.js';
15
16
  import { createSessionTokenCookie, resolveRequestAccess } from './auth.js';
@@ -69,6 +70,20 @@ function readPositiveInteger(value, fallback) {
69
70
  return fallback;
70
71
  return parsed;
71
72
  }
73
+ function resolveBooleanSetting(value, fallback) {
74
+ if (typeof value === 'boolean')
75
+ return value;
76
+ if (typeof value === 'number')
77
+ return value !== 0;
78
+ const normalized = String(value || '').trim().toLowerCase();
79
+ if (!normalized)
80
+ return fallback;
81
+ if (['1', 'true', 'yes', 'on'].includes(normalized))
82
+ return true;
83
+ if (['0', 'false', 'no', 'off'].includes(normalized))
84
+ return false;
85
+ return fallback;
86
+ }
72
87
  // Convert route pattern like '/api/taskforce/tasks/:id' to regex
73
88
  function createRoutePattern(path) {
74
89
  const keys = [];
@@ -330,20 +345,20 @@ export function createRoutes(core, context = {}) {
330
345
  const authSettings = globalSettings.auth || {};
331
346
  const authRateLimitMaxRequestsRaw = Number(authSettings.authRateLimitMaxRequests);
332
347
  const authRateLimitWindowMsRaw = Number(authSettings.authRateLimitWindowMs);
333
- const signupSettings = core.getSignupMonetizationSettings();
348
+ const onboardingPolicy = core.getOnboardingPolicy();
334
349
  return {
335
- allowSelfRegistration: authSettings.allowSelfRegistration !== false,
336
- requireVerifiedEmail: authSettings.requireVerifiedEmail !== false,
337
- defaultNewUserBetaAccess: authSettings.defaultNewUserBetaAccess === true,
338
- authRateLimitEnabled: authSettings.authRateLimitEnabled !== false,
350
+ allowSelfRegistration: resolveBooleanSetting(authSettings.allowSelfRegistration, true),
351
+ requireVerifiedEmail: resolveBooleanSetting(authSettings.requireVerifiedEmail, true),
352
+ defaultNewUserBetaAccess: resolveBooleanSetting(authSettings.defaultNewUserBetaAccess, false),
353
+ authRateLimitEnabled: resolveBooleanSetting(authSettings.authRateLimitEnabled, true),
339
354
  authRateLimitMaxRequests: Number.isFinite(authRateLimitMaxRequestsRaw) && authRateLimitMaxRequestsRaw >= 1
340
355
  ? Math.floor(authRateLimitMaxRequestsRaw)
341
356
  : 10,
342
357
  authRateLimitWindowMs: Number.isFinite(authRateLimitWindowMsRaw) && authRateLimitWindowMsRaw >= 1000
343
358
  ? Math.floor(authRateLimitWindowMsRaw)
344
359
  : 15 * 60_000,
345
- signupMonetizationStrategy: signupSettings.strategy,
346
- defaultSignupPlanVersionId: signupSettings.defaultSignupPlanVersionId
360
+ onboardingPolicyMode: onboardingPolicy.mode,
361
+ onboardingPlanVersionId: onboardingPolicy.planVersionId
347
362
  };
348
363
  };
349
364
  const deliverAuthEmail = async (kind, email, token, req) => {
@@ -1124,13 +1139,7 @@ export function createRoutes(core, context = {}) {
1124
1139
  ? authorization.slice(7).trim()
1125
1140
  : '';
1126
1141
  const requestedWorkspaceId = requestHeader(req, 'x-taskforce-workspace-id', '').trim();
1127
- const aiProfileToken = requestHeader(req, 'x-taskforce-ai-profile-token', '').trim() || null;
1128
- const aiProfileName = requestHeader(req, 'x-taskforce-ai-name', '').trim() || null;
1129
- const aiProfileDescription = requestHeader(req, 'x-taskforce-ai-description', '').trim() || null;
1130
- const aiProfileRole = requestHeader(req, 'x-taskforce-ai-role', '').trim() || null;
1131
- const aiProfileProvider = requestHeader(req, 'x-taskforce-ai-provider', '').trim() || null;
1132
- const aiProfileModel = requestHeader(req, 'x-taskforce-ai-model', '').trim() || null;
1133
- const aiProfileSurfaceType = requestHeader(req, 'x-taskforce-ai-surface-type', '').trim() || null;
1142
+ const bootstrap = parseAiProfileBootstrapHeaders(req.headers);
1134
1143
  if (bearerToken) {
1135
1144
  const tokenAuth = core.authenticateMcpAccessToken(bearerToken);
1136
1145
  const oauthAuth = tokenAuth ? null : core.authenticateMcpOAuthAccessToken(bearerToken);
@@ -1178,13 +1187,7 @@ export function createRoutes(core, context = {}) {
1178
1187
  authenticatedViaToken: tokenAuth || null,
1179
1188
  authenticatedViaOAuth: oauthAuth || null,
1180
1189
  userId: null,
1181
- aiProfileToken,
1182
- aiProfileName,
1183
- aiProfileDescription,
1184
- aiProfileRole,
1185
- aiProfileProvider,
1186
- aiProfileModel,
1187
- aiProfileSurfaceType,
1190
+ ...bootstrap,
1188
1191
  };
1189
1192
  }
1190
1193
  core.addMcpAuditLog({
@@ -1461,6 +1464,8 @@ export function createRoutes(core, context = {}) {
1461
1464
  tokenId: auth.authenticatedViaToken?.tokenId || auth.authenticatedViaOAuth?.grantId || null,
1462
1465
  aiProfileToken: auth.aiProfileToken,
1463
1466
  aiProfileName: auth.aiProfileName,
1467
+ aiProfileIcon: auth.aiProfileIcon,
1468
+ aiProfileColor: auth.aiProfileColor,
1464
1469
  aiProfileDescription: auth.aiProfileDescription,
1465
1470
  aiProfileRole: auth.aiProfileRole,
1466
1471
  aiProfileProvider: auth.aiProfileProvider,
@@ -1495,7 +1500,7 @@ export function createRoutes(core, context = {}) {
1495
1500
  };
1496
1501
  const resolveAdminRequestActor = makeResolveAdminRequestActor(core, context);
1497
1502
  const auditAdminAction = makeAuditAdminAction(core, context);
1498
- const auditAuthAction = makeAuditAuthAction(core, requestWorkspaceId);
1503
+ const auditAuthAction = makeAuditAuthAction(core, requestWorkspaceId, context);
1499
1504
  const ensureAdminRole = makeEnsureAdminRole(core, context);
1500
1505
  const ensureAuthenticatedUser = makeEnsureAuthenticatedUser();
1501
1506
  const isCollaborationPolicyEnabled = () => {
@@ -1560,6 +1565,8 @@ export function createRoutes(core, context = {}) {
1560
1565
  shouldExposeDevAuthTokens,
1561
1566
  resolveRuntimeConfigBaseUrl,
1562
1567
  resolvePublicAuthBaseUrl,
1568
+ resolveEffectiveObjectStorageConfig,
1569
+ getObjectStorageClient,
1563
1570
  });
1564
1571
  registerWorkspaceRoutes({
1565
1572
  addRoute,