@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
@@ -22,6 +22,7 @@ interface AuthorizedRequestAccess extends RequestAccessContext {
22
22
  export declare function shouldProxyCloudPath(pathname: string): boolean;
23
23
  export declare function resolveCloudProxyUpstreamBaseUrl(req: http.IncomingMessage, fallbackBaseUrl: string): string;
24
24
  export declare function resolveAuthorizedWorkspaceAccess(core: Pick<TaskforceCore, 'resolveUserAccess' | 'getSystemRole'>, access: AuthorizedRequestAccess, requestedWorkspaceId: string): AuthorizedRequestAccess;
25
+ export declare function resolveEffectiveRequestUserId(accessUserId: string, explicitUserId: string): string;
25
26
  export declare function resolveMaxPayloadBytesForPath(pathname: string, defaultMaxBytes: number): number;
26
27
  export declare function shouldRewriteSetCookieForLocalDevHost(hostHeader: string | undefined): boolean;
27
28
  export declare function writeJsonErrorIfPossible(res: http.ServerResponse, statusCode: number, payload: Record<string, unknown>): boolean;
@@ -145,6 +145,17 @@ export function resolveAuthorizedWorkspaceAccess(core, access, requestedWorkspac
145
145
  }
146
146
  return access;
147
147
  }
148
+ export function resolveEffectiveRequestUserId(accessUserId, explicitUserId) {
149
+ const normalizedAccessUserId = String(accessUserId || '').trim();
150
+ if (normalizedAccessUserId && normalizedAccessUserId !== 'anonymous') {
151
+ return normalizedAccessUserId;
152
+ }
153
+ const normalizedExplicitUserId = String(explicitUserId || '').trim();
154
+ if (normalizedExplicitUserId && normalizedExplicitUserId !== 'anonymous') {
155
+ return normalizedExplicitUserId;
156
+ }
157
+ return 'anonymous';
158
+ }
148
159
  export function resolveMaxPayloadBytesForPath(pathname, defaultMaxBytes) {
149
160
  if (pathname.startsWith('/api/taskforce/sync/')) {
150
161
  // Sync routes (especially applying local changes) often include large binary attachments
@@ -677,7 +688,10 @@ export function createStandaloneServer(options) {
677
688
  req.headers['x-taskforce-role'] = access.role;
678
689
  req.headers['x-taskforce-system-role'] = access.systemRole;
679
690
  req.headers['x-taskforce-workspace-id'] = access.workspaceId;
680
- req.headers['x-taskforce-user-id'] = access.userId;
691
+ const explicitRequestUserId = Array.isArray(req.headers['x-taskforce-user-id'])
692
+ ? String(req.headers['x-taskforce-user-id'][0] || '')
693
+ : String(req.headers['x-taskforce-user-id'] || '');
694
+ req.headers['x-taskforce-user-id'] = resolveEffectiveRequestUserId(access.userId, explicitRequestUserId);
681
695
  if (isCollaborationPolicyEnabled() && isMutation && access.role === 'read-only') {
682
696
  res.writeHead(403, { 'Content-Type': 'application/json' });
683
697
  res.end(JSON.stringify({ error: 'Forbidden: read-only role cannot mutate data.' }));
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
- import { ensureBillingWebhookAuthExclusion, ensurePublicSiteConfigAuthExclusion, isBillingWebhookPath, resolveAuthorizedWorkspaceAccess, shouldApplyAuthRateLimitForPath, shouldProxyCloudPath, writeJsonErrorIfPossible } from './index.js';
2
+ import { ensureBillingWebhookAuthExclusion, ensurePublicSiteConfigAuthExclusion, isBillingWebhookPath, resolveEffectiveRequestUserId, resolveAuthorizedWorkspaceAccess, shouldApplyAuthRateLimitForPath, shouldProxyCloudPath, writeJsonErrorIfPossible } from './index.js';
3
3
  describe('server index helper policies', () => {
4
4
  it('adds webhook path to auth exclusions without duplicates', () => {
5
5
  const base = ['/api/taskforce/health', '/api/taskforce/auth'];
@@ -86,6 +86,7 @@ describe('shouldProxyCloudPath', () => {
86
86
  expect(shouldProxyCloudPath('/api/taskforce/admin/users')).toBe(true);
87
87
  expect(shouldProxyCloudPath('/api/taskforce/billing/plans')).toBe(true);
88
88
  expect(shouldProxyCloudPath('/api/taskforce/auth/login')).toBe(true);
89
+ expect(shouldProxyCloudPath('/api/taskforce/account/team-management-access')).toBe(false);
89
90
  expect(shouldProxyCloudPath('/api/taskforce/public/site-config')).toBe(true);
90
91
  expect(shouldProxyCloudPath('/api/taskforce/public/site-config-script')).toBe(true);
91
92
  });
@@ -148,3 +149,15 @@ describe('resolveAuthorizedWorkspaceAccess', () => {
148
149
  expect(next.workspaceId).toBe('workspace-personal');
149
150
  });
150
151
  });
152
+ describe('resolveEffectiveRequestUserId', () => {
153
+ it('prefers the authenticated access user when present', () => {
154
+ expect(resolveEffectiveRequestUserId('user-authenticated', 'user-explicit')).toBe('user-authenticated');
155
+ });
156
+ it('preserves an explicit local actor header when auth access is anonymous', () => {
157
+ expect(resolveEffectiveRequestUserId('anonymous', 'user-local-actor')).toBe('user-local-actor');
158
+ expect(resolveEffectiveRequestUserId('', 'user-local-actor')).toBe('user-local-actor');
159
+ });
160
+ it('falls back to anonymous when neither source has a user id', () => {
161
+ expect(resolveEffectiveRequestUserId('anonymous', '')).toBe('anonymous');
162
+ });
163
+ });
@@ -59,6 +59,7 @@ import { normalizeStorageIntegrityScheduleSettings, resolveStorageIntegritySched
59
59
  import { resolveVirusScanConfigFromEnv } from '../../security/virusScan.js';
60
60
  import { applyPrefixedRateLimitHeaders } from '../rateLimit.js';
61
61
  import { createTaskforceMcpServer, isMcpWriteToolName } from '../../mcp/runtime.js';
62
+ import { parseAiProfileBootstrapHeaders } from '../../mcp/aiProfileBootstrap.js';
62
63
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
63
64
  import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
64
65
  import { randomUUID } from 'crypto';
@@ -81,6 +82,20 @@ export function registerAdminRoutes(deps) {
81
82
  const globalSettings = core.getGlobalSettings();
82
83
  return resolveEffectiveEmailConfig(process.env, globalSettings.email || null);
83
84
  };
85
+ const resolveBooleanSetting = (value, fallback) => {
86
+ if (typeof value === 'boolean')
87
+ return value;
88
+ if (typeof value === 'number')
89
+ return value !== 0;
90
+ const normalized = String(value || '').trim().toLowerCase();
91
+ if (!normalized)
92
+ return fallback;
93
+ if (['1', 'true', 'yes', 'on'].includes(normalized))
94
+ return true;
95
+ if (['0', 'false', 'no', 'off'].includes(normalized))
96
+ return false;
97
+ return fallback;
98
+ };
84
99
  const getAuthBehavior = () => {
85
100
  const globalSettings = core.getGlobalSettings();
86
101
  const authSettings = globalSettings.auth || {};
@@ -88,10 +103,10 @@ export function registerAdminRoutes(deps) {
88
103
  const authRateLimitWindowMsRaw = Number(authSettings.authRateLimitWindowMs);
89
104
  const signupSettings = core.getSignupMonetizationSettings();
90
105
  return {
91
- allowSelfRegistration: authSettings.allowSelfRegistration !== false,
92
- requireVerifiedEmail: authSettings.requireVerifiedEmail !== false,
93
- defaultNewUserBetaAccess: authSettings.defaultNewUserBetaAccess === true,
94
- authRateLimitEnabled: authSettings.authRateLimitEnabled !== false,
106
+ allowSelfRegistration: resolveBooleanSetting(authSettings.allowSelfRegistration, true),
107
+ requireVerifiedEmail: resolveBooleanSetting(authSettings.requireVerifiedEmail, true),
108
+ defaultNewUserBetaAccess: resolveBooleanSetting(authSettings.defaultNewUserBetaAccess, false),
109
+ authRateLimitEnabled: resolveBooleanSetting(authSettings.authRateLimitEnabled, true),
95
110
  authRateLimitMaxRequests: Number.isFinite(authRateLimitMaxRequestsRaw) && authRateLimitMaxRequestsRaw >= 1
96
111
  ? Math.floor(authRateLimitMaxRequestsRaw)
97
112
  : 10,
@@ -106,8 +121,8 @@ export function registerAdminRoutes(deps) {
106
121
  const globalSettings = core.getGlobalSettings();
107
122
  const siteSettings = globalSettings.site || {};
108
123
  return {
109
- showRunTaskforceLocally: siteSettings.showRunTaskforceLocally !== false,
110
- pricingPageEnabled: siteSettings.pricingPageEnabled !== false
124
+ showRunTaskforceLocally: resolveBooleanSetting(siteSettings.showRunTaskforceLocally, true),
125
+ pricingPageEnabled: resolveBooleanSetting(siteSettings.pricingPageEnabled, true)
111
126
  };
112
127
  };
113
128
  const resolveEffectiveVirusScanSettings = () => {
@@ -264,13 +279,7 @@ export function registerAdminRoutes(deps) {
264
279
  ? authorization.slice(7).trim()
265
280
  : '';
266
281
  const requestedWorkspaceId = requestHeader(req, 'x-taskforce-workspace-id', '').trim();
267
- const aiProfileToken = requestHeader(req, 'x-taskforce-ai-profile-token', '').trim() || null;
268
- const aiProfileName = requestHeader(req, 'x-taskforce-ai-name', '').trim() || null;
269
- const aiProfileDescription = requestHeader(req, 'x-taskforce-ai-description', '').trim() || null;
270
- const aiProfileRole = requestHeader(req, 'x-taskforce-ai-role', '').trim() || null;
271
- const aiProfileProvider = requestHeader(req, 'x-taskforce-ai-provider', '').trim() || null;
272
- const aiProfileModel = requestHeader(req, 'x-taskforce-ai-model', '').trim() || null;
273
- const aiProfileSurfaceType = requestHeader(req, 'x-taskforce-ai-surface-type', '').trim() || null;
282
+ const bootstrap = parseAiProfileBootstrapHeaders(req.headers);
274
283
  if (bearerToken) {
275
284
  const tokenAuth = core.authenticateMcpAccessToken(bearerToken);
276
285
  const oauthAuth = tokenAuth ? null : core.authenticateMcpOAuthAccessToken(bearerToken);
@@ -318,13 +327,7 @@ export function registerAdminRoutes(deps) {
318
327
  authenticatedViaToken: tokenAuth || null,
319
328
  authenticatedViaOAuth: oauthAuth || null,
320
329
  userId: null,
321
- aiProfileToken,
322
- aiProfileName,
323
- aiProfileDescription,
324
- aiProfileRole,
325
- aiProfileProvider,
326
- aiProfileModel,
327
- aiProfileSurfaceType,
330
+ ...bootstrap,
328
331
  };
329
332
  }
330
333
  core.addMcpAuditLog({
@@ -1812,7 +1815,7 @@ export function registerAdminRoutes(deps) {
1812
1815
  addRoute('OPTIONS', '/mcp', async (_req, res) => {
1813
1816
  res.writeHead(204, {
1814
1817
  'Access-Control-Allow-Origin': '*',
1815
- 'Access-Control-Allow-Headers': 'authorization, content-type, accept, last-event-id, mcp-protocol-version, mcp-session-id, x-taskforce-workspace-id, x-taskforce-ai-profile-token, x-taskforce-ai-name, x-taskforce-ai-description, x-taskforce-ai-role, x-taskforce-ai-provider, x-taskforce-ai-model, x-taskforce-ai-surface-type',
1818
+ 'Access-Control-Allow-Headers': 'authorization, content-type, accept, last-event-id, mcp-protocol-version, mcp-session-id, x-taskforce-workspace-id, x-taskforce-ai-profile-token, x-taskforce-ai-name, x-taskforce-ai-icon, x-taskforce-ai-color, x-taskforce-ai-description, x-taskforce-ai-role, x-taskforce-ai-provider, x-taskforce-ai-model, x-taskforce-ai-surface-type',
1816
1819
  'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS'
1817
1820
  });
1818
1821
  res.end();
@@ -1820,7 +1823,7 @@ export function registerAdminRoutes(deps) {
1820
1823
  addRoute('OPTIONS', '/mcp/', async (_req, res) => {
1821
1824
  res.writeHead(204, {
1822
1825
  'Access-Control-Allow-Origin': '*',
1823
- 'Access-Control-Allow-Headers': 'authorization, content-type, accept, last-event-id, mcp-protocol-version, mcp-session-id, x-taskforce-workspace-id, x-taskforce-ai-profile-token, x-taskforce-ai-name, x-taskforce-ai-description, x-taskforce-ai-role, x-taskforce-ai-provider, x-taskforce-ai-model, x-taskforce-ai-surface-type',
1826
+ 'Access-Control-Allow-Headers': 'authorization, content-type, accept, last-event-id, mcp-protocol-version, mcp-session-id, x-taskforce-workspace-id, x-taskforce-ai-profile-token, x-taskforce-ai-name, x-taskforce-ai-icon, x-taskforce-ai-color, x-taskforce-ai-description, x-taskforce-ai-role, x-taskforce-ai-provider, x-taskforce-ai-model, x-taskforce-ai-surface-type',
1824
1827
  'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS'
1825
1828
  });
1826
1829
  res.end();
@@ -21,6 +21,7 @@
21
21
  * POST /api/taskforce/auth/logout
22
22
  * GET /api/taskforce/account/access-status
23
23
  * GET /api/taskforce/account/entitlements
24
+ * GET /api/taskforce/account/team-management-access
24
25
  * GET /api/taskforce/account/plan-preview
25
26
  * GET /api/taskforce/auth/workspace-members
26
27
  * GET /api/taskforce/workspace/assignee-options
@@ -36,6 +37,8 @@
36
37
  import type { IncomingMessage, ServerResponse } from 'http';
37
38
  import type { TaskforceCore } from '../../core/Taskforce.js';
38
39
  import type { RouteHandler, RouteContext } from '../routes.js';
40
+ import type { ResolvedObjectStorageConfig } from '../../storage/objectStorage.js';
41
+ import { ObjectStorageClient } from '../../storage/objectStorageClient.js';
39
42
  export interface AuthRouteDependencies {
40
43
  addRoute: (method: string, path: string, handler: RouteHandler) => void;
41
44
  core: TaskforceCore;
@@ -57,5 +60,7 @@ export interface AuthRouteDependencies {
57
60
  shouldExposeDevAuthTokens: () => boolean;
58
61
  resolveRuntimeConfigBaseUrl: (req: IncomingMessage) => string;
59
62
  resolvePublicAuthBaseUrl: (req: IncomingMessage) => string;
63
+ resolveEffectiveObjectStorageConfig: () => ResolvedObjectStorageConfig;
64
+ getObjectStorageClient: () => ObjectStorageClient | null;
60
65
  }
61
66
  export declare function registerAuthRoutes(deps: AuthRouteDependencies): void;