@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.
- package/dist/Taskforce.module.css +37 -2
- package/dist/TaskforceCore.filter-persistence.test.js +1 -1
- package/dist/TaskforceCore.js +72 -33
- package/dist/TaskforceCore.test.js +848 -130
- package/dist/components/features/TaskSettings.js +14 -82
- package/dist/components/features/TaskSettings.test.js +33 -70
- package/dist/components/features/settings/TaxonomyLibraryManager.js +8 -2
- package/dist/components/features/settings/TaxonomyLibraryManager.test.js +1 -1
- package/dist/components/task/TaskActionHeader.js +6 -3
- package/dist/components/task/TaskCard.js +6 -3
- package/dist/components/task/TaskForm.js +2 -2
- package/dist/components/task/TaskForm.test.js +41 -2
- package/dist/components/task/TaskKanban.test.js +17 -0
- package/dist/components/ui/ReferenceBadgeButton.js +1 -1
- package/dist/components/views/PlansPage.d.ts +3 -1
- package/dist/components/views/PlansPage.js +109 -49
- package/dist/components/views/PlansPage.test.d.ts +1 -0
- package/dist/components/views/PlansPage.test.js +100 -0
- package/dist/components/views/StandaloneLayout.d.ts +1 -0
- package/dist/components/views/StandaloneLayout.js +473 -256
- package/dist/components/views/panels/PlanningDrawer.js +18 -1
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +48 -0
- package/dist/components/views/standalone/modals/AccountHubModal.js +36 -0
- package/dist/components/views/standalone/modals/AccountHubModal.test.d.ts +1 -0
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +26 -0
- package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.d.ts +9 -0
- package/dist/components/views/standalone/modals/CreateWorkspaceConfirmModal.js +8 -0
- package/dist/components/views/standalone/modals/EditProfileModal.d.ts +26 -0
- package/dist/components/views/standalone/modals/EditProfileModal.js +10 -0
- package/dist/components/views/standalone/modals/HelpModal.d.ts +9 -0
- package/dist/components/views/standalone/modals/HelpModal.js +8 -0
- package/dist/components/views/standalone/modals/ScheduleWarningModal.d.ts +13 -0
- package/dist/components/views/standalone/modals/ScheduleWarningModal.js +6 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +61 -0
- package/dist/components/views/standalone/modals/SyncStatusModal.js +38 -0
- package/dist/components/views/standalone/modals/TeamManagementModal.d.ts +64 -0
- package/dist/components/views/standalone/modals/TeamManagementModal.js +10 -0
- package/dist/components/views/standalone/modals/types.d.ts +2 -0
- package/dist/components/views/standalone/modals/types.js +1 -0
- package/dist/components/views/teamManagementAccess.d.ts +1 -1
- package/dist/components/views/teamManagementAccess.js +2 -2
- package/dist/components/views/teamManagementAccess.test.js +3 -3
- package/dist/config/deployment.js +2 -2
- package/dist/config/deployment.test.js +5 -3
- package/dist/core/AiProfileService.js +7 -2
- package/dist/core/AiProfiles.test.js +19 -0
- package/dist/core/EntitlementsPolicy.test.js +2 -2
- package/dist/core/GlobalSettingsService.js +78 -18
- package/dist/core/PlanEntitlementService.d.ts +29 -5
- package/dist/core/PlanEntitlementService.js +297 -219
- package/dist/core/SignupMonetizationSettings.test.js +173 -49
- package/dist/core/SyncReconciliationService.d.ts +2 -0
- package/dist/core/SyncReconciliationService.js +3 -0
- package/dist/core/SystemAdmin.test.js +186 -96
- package/dist/core/TaskAuditTimeline.test.js +40 -0
- package/dist/core/Taskforce.d.ts +100 -10
- package/dist/core/Taskforce.ids.test.js +133 -0
- package/dist/core/Taskforce.js +459 -127
- package/dist/core/Taskforce.mcpAuth.test.js +0 -2
- package/dist/core/UserProfileAvatarDrafts.test.d.ts +1 -0
- package/dist/core/UserProfileAvatarDrafts.test.js +111 -0
- package/dist/core/taskReferencePolicy.d.ts +28 -0
- package/dist/core/taskReferencePolicy.js +189 -0
- package/dist/core/types.d.ts +13 -12
- package/dist/hooks/tasks/useTaskFormActions.js +3 -0
- package/dist/hooks/useSyncOrchestrator.js +17 -3
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +97 -5
- package/dist/hooks/useTaskData.js +3 -2
- package/dist/hooks/useTaskData.test.js +66 -0
- package/dist/hooks/useTaskforce.d.ts +8 -0
- package/dist/hooks/useTaskforce.js +72 -19
- package/dist/hooks/useTaskforce.sync-behavior.test.js +185 -6
- package/dist/mcp/aiProfileBootstrap.d.ts +29 -0
- package/dist/mcp/aiProfileBootstrap.js +80 -0
- package/dist/mcp/aiProfileBootstrap.test.d.ts +1 -0
- package/dist/mcp/aiProfileBootstrap.test.js +68 -0
- package/dist/mcp/clientIntegrations.d.ts +2 -8
- package/dist/mcp/clientIntegrations.js +21 -40
- package/dist/mcp/clientIntegrations.test.js +28 -2
- package/dist/mcp/clientProfileDefaults.d.ts +12 -0
- package/dist/mcp/clientProfileDefaults.js +37 -0
- package/dist/mcp/runtime.d.ts +10 -7
- package/dist/mcp/runtime.js +131 -48
- package/dist/mcp/runtime.test.js +321 -83
- package/dist/migrations/billingSchemaParity.test.js +3 -0
- package/dist/migrations/taskSchemaMigrations.js +68 -1
- package/dist/qaOpen.test.d.ts +1 -0
- package/dist/qaOpen.test.js +56 -0
- package/dist/server/index.cookieProxy.test.js +2 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +17 -1
- package/dist/server/index.test.js +15 -1
- package/dist/server/mockStripe.d.ts +1 -0
- package/dist/server/mockStripe.js +2 -0
- package/dist/server/routes/admin.js +105 -45
- package/dist/server/routes/auth.d.ts +6 -0
- package/dist/server/routes/auth.js +505 -30
- package/dist/server/routes/billing.js +517 -24
- package/dist/server/routes/billing.test.js +967 -45
- package/dist/server/routes/documents.js +6 -1
- package/dist/server/routes/shared.d.ts +1 -1
- package/dist/server/routes/shared.js +16 -6
- package/dist/server/routes/sync.integration.test.js +290 -0
- package/dist/server/routes/sync.js +234 -1922
- package/dist/server/routes/tasks.js +18 -4
- package/dist/server/routes.js +29 -22
- package/dist/server/routes.test.js +639 -82
- package/dist/shared/runtimeContract.d.ts +1 -1
- package/dist/sync/cloudSyncApi.d.ts +1 -0
- package/dist/sync/collaborationSyncPayload.d.ts +17 -0
- package/dist/sync/collaborationSyncPayload.js +131 -0
- package/dist/sync/collaborationSyncPayload.test.d.ts +1 -0
- package/dist/sync/collaborationSyncPayload.test.js +104 -0
- package/dist/sync/collaborationSyncState.d.ts +15 -0
- package/dist/sync/collaborationSyncState.js +60 -0
- package/dist/sync/contentSyncPayload.d.ts +45 -0
- package/dist/sync/contentSyncPayload.js +104 -0
- package/dist/sync/contentSyncPayload.test.d.ts +1 -0
- package/dist/sync/contentSyncPayload.test.js +104 -0
- package/dist/sync/contentSyncState.d.ts +98 -0
- package/dist/sync/contentSyncState.js +1004 -0
- package/dist/sync/planningSyncPayload.d.ts +9 -0
- package/dist/sync/planningSyncPayload.js +82 -0
- package/dist/sync/planningSyncPayload.test.d.ts +1 -0
- package/dist/sync/planningSyncPayload.test.js +68 -0
- package/dist/sync/syncApplyHandlers.d.ts +83 -0
- package/dist/sync/syncApplyHandlers.js +445 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +21 -8
- package/dist/sync/taskSyncPayload.d.ts +33 -0
- package/dist/sync/taskSyncPayload.js +126 -0
- package/dist/sync/taskSyncPayload.test.d.ts +1 -0
- package/dist/sync/taskSyncPayload.test.js +54 -0
- package/dist/sync/workspacePullFeed.d.ts +38 -0
- package/dist/sync/workspacePullFeed.js +349 -0
- package/dist/sync/workspacePullFeed.test.d.ts +1 -0
- package/dist/sync/workspacePullFeed.test.js +278 -0
- package/dist/sync/workspaceSyncModel.d.ts +4 -1
- package/dist/sync/workspaceSyncModel.js +9 -2
- package/dist/sync/workspaceSyncModel.test.js +29 -0
- package/dist/test/setup.js +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/ui/assets/{AgentsModule-Bdq3T1Ts.js → AgentsModule-CpsTmrIW.js} +1 -1
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-jKUVo-PJ.js → AnnotatedAttachmentWorkspace-C_TmXZwA.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-DuQa-uIC.js → DocumentWorkspace-C3GyzrWm.js} +2 -2
- package/dist/ui/assets/{InitiativesModule-C8Pi2VTk.js → InitiativesModule-4-Rh2K2n.js} +1 -1
- package/dist/ui/assets/PlansPage-BP7AYOqr.js +1 -0
- package/dist/ui/assets/TaskSettings-BOC5F6Ag.js +8 -0
- package/dist/ui/assets/{TaskSettings-BwB9NtmJ.css → TaskSettings-CnIBL_Eb.css} +1 -1
- package/dist/ui/assets/{WorkflowsModule-b6TLuHwJ.js → WorkflowsModule-CGk9s3NJ.js} +1 -1
- package/dist/ui/assets/index-CLIMgR6g.js +6 -0
- package/dist/ui/assets/index-DneETxcu.css +1 -0
- package/dist/ui/assets/{vendor-icons-QZyhEwgT.js → vendor-icons-pWocEipT.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/accountProfileSummaryCache.d.ts +31 -0
- package/dist/utils/accountProfileSummaryCache.js +97 -0
- package/dist/utils/accountProfileSummaryCache.test.d.ts +1 -0
- package/dist/utils/accountProfileSummaryCache.test.js +63 -0
- package/dist/utils/taskActivity.js +17 -4
- package/dist/utils/taskActivity.test.js +27 -0
- package/dist/utils/taskNormalization.js +10 -2
- package/dist/utils/taskReferences.d.ts +11 -1
- package/dist/utils/taskReferences.js +33 -1
- package/package.json +4 -3
- package/scripts/qa-open-lib.mjs +175 -0
- package/scripts/qa-open-lib.mjs.d.ts +49 -0
- package/scripts/qa-open.mjs +352 -0
- package/dist/ui/assets/PlansPage-B6BDECSi.js +0 -1
- package/dist/ui/assets/TaskSettings-DUJgRTPU.js +0 -8
- package/dist/ui/assets/index-BiiF1cLQ.css +0 -1
- 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, {
|
|
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
|
|
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;
|
package/dist/server/routes.js
CHANGED
|
@@ -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
|
|
348
|
+
const onboardingPolicy = core.getOnboardingPolicy();
|
|
334
349
|
return {
|
|
335
|
-
allowSelfRegistration: authSettings.allowSelfRegistration
|
|
336
|
-
requireVerifiedEmail: authSettings.requireVerifiedEmail
|
|
337
|
-
defaultNewUserBetaAccess: authSettings.defaultNewUserBetaAccess
|
|
338
|
-
authRateLimitEnabled: authSettings.authRateLimitEnabled
|
|
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
|
-
|
|
346
|
-
|
|
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
|
|
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
|
-
|
|
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,
|