@taskforcehq/taskforce 0.3.168
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/README.md +241 -0
- package/dist/Taskforce.d.ts +3 -0
- package/dist/Taskforce.js +3 -0
- package/dist/Taskforce.module.css +7587 -0
- package/dist/TaskforceCore.CategoryFallback.test.d.ts +1 -0
- package/dist/TaskforceCore.CategoryFallback.test.js +98 -0
- package/dist/TaskforceCore.d.ts +12 -0
- package/dist/TaskforceCore.js +729 -0
- package/dist/TaskforceCore.test.d.ts +1 -0
- package/dist/TaskforceCore.test.js +2132 -0
- package/dist/TaskforceScreenshot.d.ts +11 -0
- package/dist/TaskforceScreenshot.js +113 -0
- package/dist/TaskforceWidget.d.ts +6 -0
- package/dist/TaskforceWidget.js +101 -0
- package/dist/TaskforceWidget.test.d.ts +1 -0
- package/dist/TaskforceWidget.test.js +92 -0
- package/dist/UnsavedChangesRelaxed.test.d.ts +1 -0
- package/dist/UnsavedChangesRelaxed.test.js +16 -0
- package/dist/__tests__/localizationCatalogs.test.d.ts +1 -0
- package/dist/__tests__/localizationCatalogs.test.js +37 -0
- package/dist/__tests__/planParser.test.d.ts +1 -0
- package/dist/__tests__/planParser.test.js +183 -0
- package/dist/__tests__/releaseVersion.test.d.ts +1 -0
- package/dist/__tests__/releaseVersion.test.js +32 -0
- package/dist/__tests__/structuredCommentValidation.test.d.ts +1 -0
- package/dist/__tests__/structuredCommentValidation.test.js +31 -0
- package/dist/__tests__/structuredDocValidation.test.d.ts +1 -0
- package/dist/__tests__/structuredDocValidation.test.js +30 -0
- package/dist/__tests__/templateEngine.test.d.ts +1 -0
- package/dist/__tests__/templateEngine.test.js +150 -0
- package/dist/__tests__/templates.test.d.ts +1 -0
- package/dist/__tests__/templates.test.js +45 -0
- package/dist/__tests__/workflowDocumentFixtures.test.d.ts +1 -0
- package/dist/__tests__/workflowDocumentFixtures.test.js +78 -0
- package/dist/__tests__/workflowExportMatrix.test.d.ts +1 -0
- package/dist/__tests__/workflowExportMatrix.test.js +113 -0
- package/dist/__tests__/workflowExportSnapshots.test.d.ts +1 -0
- package/dist/__tests__/workflowExportSnapshots.test.js +28 -0
- package/dist/__tests__/workflowGeneration.test.d.ts +1 -0
- package/dist/__tests__/workflowGeneration.test.js +12 -0
- package/dist/__tests__/workflowSimulation.test.d.ts +1 -0
- package/dist/__tests__/workflowSimulation.test.js +113 -0
- package/dist/__tests__/workflowV2Policy.test.d.ts +1 -0
- package/dist/__tests__/workflowV2Policy.test.js +80 -0
- package/dist/api.d.ts +30 -0
- package/dist/api.js +85 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +217 -0
- package/dist/compat/priorityCompat.d.ts +2 -0
- package/dist/compat/priorityCompat.js +24 -0
- package/dist/components/features/DocumentGenerateModal.d.ts +9 -0
- package/dist/components/features/DocumentGenerateModal.js +114 -0
- package/dist/components/features/DocumentIndex.d.ts +19 -0
- package/dist/components/features/DocumentIndex.js +51 -0
- package/dist/components/features/DocumentViewer.d.ts +9 -0
- package/dist/components/features/DocumentViewer.js +253 -0
- package/dist/components/features/DocumentWorkspace.d.ts +21 -0
- package/dist/components/features/DocumentWorkspace.js +88 -0
- package/dist/components/features/TaskSettings.d.ts +209 -0
- package/dist/components/features/TaskSettings.js +500 -0
- package/dist/components/features/TaskSettings.test.d.ts +1 -0
- package/dist/components/features/TaskSettings.test.js +308 -0
- package/dist/components/features/settings/CategoryManager.d.ts +19 -0
- package/dist/components/features/settings/CategoryManager.js +113 -0
- package/dist/components/features/settings/TaxonomyEditor.d.ts +8 -0
- package/dist/components/features/settings/TaxonomyEditor.js +98 -0
- package/dist/components/features/settings/TaxonomyManager 2.d.ts +52 -0
- package/dist/components/features/settings/TaxonomyManager 2.js +75 -0
- package/dist/components/features/settings/TaxonomyManager.d.ts +54 -0
- package/dist/components/features/settings/TaxonomyManager.js +77 -0
- package/dist/components/features/settings/TypeManager.d.ts +10 -0
- package/dist/components/features/settings/TypeManager.js +50 -0
- package/dist/components/features/settings/WorkflowEditorPrototype.d.ts +15 -0
- package/dist/components/features/settings/WorkflowEditorPrototype.js +245 -0
- package/dist/components/task/TaskActionHeader.d.ts +20 -0
- package/dist/components/task/TaskActionHeader.js +13 -0
- package/dist/components/task/TaskCard.d.ts +47 -0
- package/dist/components/task/TaskCard.js +326 -0
- package/dist/components/task/TaskCard.test.d.ts +1 -0
- package/dist/components/task/TaskCard.test.js +95 -0
- package/dist/components/task/TaskContextUpload.d.ts +12 -0
- package/dist/components/task/TaskContextUpload.js +393 -0
- package/dist/components/task/TaskContextUpload.test.d.ts +1 -0
- package/dist/components/task/TaskContextUpload.test.js +189 -0
- package/dist/components/task/TaskForm.d.ts +105 -0
- package/dist/components/task/TaskForm.js +241 -0
- package/dist/components/task/TaskForm.test.d.ts +1 -0
- package/dist/components/task/TaskForm.test.js +288 -0
- package/dist/components/task/TaskKanban 2.d.ts +76 -0
- package/dist/components/task/TaskKanban 2.js +1004 -0
- package/dist/components/task/TaskKanban.d.ts +76 -0
- package/dist/components/task/TaskKanban.empty-column-drop.test.d.ts +1 -0
- package/dist/components/task/TaskKanban.empty-column-drop.test.js +66 -0
- package/dist/components/task/TaskKanban.js +1026 -0
- package/dist/components/task/TaskKanban.test.d.ts +1 -0
- package/dist/components/task/TaskKanban.test.js +46 -0
- package/dist/components/task/TaskList.d.ts +74 -0
- package/dist/components/task/TaskList.js +38 -0
- package/dist/components/task/TaskList.test.d.ts +1 -0
- package/dist/components/task/TaskList.test.js +270 -0
- package/dist/components/task/TaskScreenshotSection.d.ts +15 -0
- package/dist/components/task/TaskScreenshotSection.js +22 -0
- package/dist/components/ui/LevelSelector.d.ts +13 -0
- package/dist/components/ui/LevelSelector.js +25 -0
- package/dist/components/ui/LevelSelector.test.d.ts +1 -0
- package/dist/components/ui/LevelSelector.test.js +55 -0
- package/dist/components/ui/Markdown.d.ts +6 -0
- package/dist/components/ui/Markdown.js +94 -0
- package/dist/components/ui/Markdown.test.d.ts +1 -0
- package/dist/components/ui/Markdown.test.js +38 -0
- package/dist/components/ui/Modal.d.ts +16 -0
- package/dist/components/ui/Modal.js +49 -0
- package/dist/components/ui/MultiSelectFilter.d.ts +10 -0
- package/dist/components/ui/MultiSelectFilter.js +71 -0
- package/dist/components/ui/MultiSelectFilter.test.d.ts +1 -0
- package/dist/components/ui/MultiSelectFilter.test.js +74 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +17 -0
- package/dist/components/ui/TaxonomyDropdown.js +145 -0
- package/dist/components/ui/TaxonomyDropdown.test.d.ts +1 -0
- package/dist/components/ui/TaxonomyDropdown.test.js +130 -0
- package/dist/components/views/StandaloneLayout 2.d.ts +8 -0
- package/dist/components/views/StandaloneLayout 2.js +1660 -0
- package/dist/components/views/StandaloneLayout.d.ts +8 -0
- package/dist/components/views/StandaloneLayout.js +2117 -0
- package/dist/components/views/WidgetView.d.ts +8 -0
- package/dist/components/views/WidgetView.js +221 -0
- package/dist/config/envSchema.d.ts +28 -0
- package/dist/config/envSchema.js +374 -0
- package/dist/config/envSchema.test.d.ts +1 -0
- package/dist/config/envSchema.test.js +97 -0
- package/dist/config/surfaceBase.d.ts +2 -0
- package/dist/config/surfaceBase.js +8 -0
- package/dist/core/BulkUpdateFieldsPreview.test.d.ts +1 -0
- package/dist/core/BulkUpdateFieldsPreview.test.js +62 -0
- package/dist/core/CompletedAt.test.d.ts +1 -0
- package/dist/core/CompletedAt.test.js +44 -0
- package/dist/core/CreatedBy.test.d.ts +1 -0
- package/dist/core/CreatedBy.test.js +60 -0
- package/dist/core/EntitlementsPolicy.test.d.ts +1 -0
- package/dist/core/EntitlementsPolicy.test.js +145 -0
- package/dist/core/InitiativeTemplates.test.d.ts +1 -0
- package/dist/core/InitiativeTemplates.test.js +50 -0
- package/dist/core/ParentLifecycle.test.d.ts +1 -0
- package/dist/core/ParentLifecycle.test.js +98 -0
- package/dist/core/ScheduleFields.test.d.ts +1 -0
- package/dist/core/ScheduleFields.test.js +197 -0
- package/dist/core/SetupState.test.d.ts +1 -0
- package/dist/core/SetupState.test.js +113 -0
- package/dist/core/SystemAdmin.test.d.ts +1 -0
- package/dist/core/SystemAdmin.test.js +295 -0
- package/dist/core/TaskTaxonomyValidation.test.d.ts +1 -0
- package/dist/core/TaskTaxonomyValidation.test.js +64 -0
- package/dist/core/Taskforce.d.ts +1063 -0
- package/dist/core/Taskforce.ids.test.d.ts +1 -0
- package/dist/core/Taskforce.ids.test.js +168 -0
- package/dist/core/Taskforce.js +5981 -0
- package/dist/core/Taskforce.realtimeMutation.test.d.ts +1 -0
- package/dist/core/Taskforce.realtimeMutation.test.js +76 -0
- package/dist/core/WorkspaceDelete.test.d.ts +1 -0
- package/dist/core/WorkspaceDelete.test.js +140 -0
- package/dist/core/WorkspacePermissions.test.d.ts +1 -0
- package/dist/core/WorkspacePermissions.test.js +151 -0
- package/dist/core/WorkspacePlanMode.test.d.ts +1 -0
- package/dist/core/WorkspacePlanMode.test.js +104 -0
- package/dist/hooks/authGuardPolicy.d.ts +26 -0
- package/dist/hooks/authGuardPolicy.js +32 -0
- package/dist/hooks/authGuardPolicy.test.d.ts +1 -0
- package/dist/hooks/authGuardPolicy.test.js +76 -0
- package/dist/hooks/useDraggable.d.ts +12 -0
- package/dist/hooks/useDraggable.js +65 -0
- package/dist/hooks/useRealtimeSync.d.ts +24 -0
- package/dist/hooks/useRealtimeSync.js +275 -0
- package/dist/hooks/useRealtimeSync.test.d.ts +1 -0
- package/dist/hooks/useRealtimeSync.test.js +284 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +164 -0
- package/dist/hooks/useSyncOrchestrator.js +1427 -0
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.d.ts +1 -0
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +367 -0
- package/dist/hooks/useTaskforce.d.ts +727 -0
- package/dist/hooks/useTaskforce.js +4396 -0
- package/dist/hooks/useTaskforce.priority-filters.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.priority-filters.test.js +33 -0
- package/dist/hooks/useWorkspaceSyncController.d.ts +80 -0
- package/dist/hooks/useWorkspaceSyncController.js +598 -0
- package/dist/hooks/useWorkspaceSyncController.test.d.ts +1 -0
- package/dist/hooks/useWorkspaceSyncController.test.js +236 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/localization/index.d.ts +8 -0
- package/dist/localization/index.js +81 -0
- package/dist/localization/locales/en-US.d.ts +151 -0
- package/dist/localization/locales/en-US.js +150 -0
- package/dist/localization/locales/es-419.d.ts +2 -0
- package/dist/localization/locales/es-419.js +150 -0
- package/dist/localization/locales/pt-BR.d.ts +2 -0
- package/dist/localization/locales/pt-BR.js +150 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +33 -0
- package/dist/mcp/optionResolution.d.ts +14 -0
- package/dist/mcp/optionResolution.js +126 -0
- package/dist/mcp/optionResolution.test.d.ts +1 -0
- package/dist/mcp/optionResolution.test.js +39 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +1793 -0
- package/dist/mcp/structuredCommentValidation.d.ts +6 -0
- package/dist/mcp/structuredCommentValidation.js +56 -0
- package/dist/mcp/structuredDocValidation.d.ts +6 -0
- package/dist/mcp/structuredDocValidation.js +75 -0
- package/dist/migrations/billingSchemaParity.test.d.ts +1 -0
- package/dist/migrations/billingSchemaParity.test.js +46 -0
- package/dist/migrations/clientMigrations.d.ts +9 -0
- package/dist/migrations/clientMigrations.js +74 -0
- package/dist/migrations/flags.d.ts +6 -0
- package/dist/migrations/flags.js +8 -0
- package/dist/migrations/taskMigrations.d.ts +71 -0
- package/dist/migrations/taskMigrations.js +236 -0
- package/dist/migrations/taskMigrations.test.d.ts +1 -0
- package/dist/migrations/taskMigrations.test.js +34 -0
- package/dist/migrations/taskSchemaMigrations.d.ts +11 -0
- package/dist/migrations/taskSchemaMigrations.js +453 -0
- package/dist/plugins/index.d.ts +10 -0
- package/dist/plugins/index.js +10 -0
- package/dist/plugins/vite.d.ts +19 -0
- package/dist/plugins/vite.js +271 -0
- package/dist/public/android-chrome-192x192.png +0 -0
- package/dist/public/android-chrome-512x512.png +0 -0
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/favicon-16x16.png +0 -0
- package/dist/public/favicon-32x32.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/favicon.png +0 -0
- package/dist/public/site.webmanifest +1 -0
- package/dist/public/taskforce.png +0 -0
- package/dist/resources/templates/WORKFLOW_V2_POLICY.md +55 -0
- package/dist/resources/templates/environments/aider.yaml +14 -0
- package/dist/resources/templates/environments/antigravity.yaml +10 -0
- package/dist/resources/templates/environments/claude.yaml +10 -0
- package/dist/resources/templates/environments/cline.yaml +10 -0
- package/dist/resources/templates/environments/codex.yaml +13 -0
- package/dist/resources/templates/environments/copilot.yaml +10 -0
- package/dist/resources/templates/environments/cursor.yaml +9 -0
- package/dist/resources/templates/environments/gemini.yaml +9 -0
- package/dist/resources/templates/environments/windsurf.yaml +10 -0
- package/dist/resources/templates/workflow-sources/README.md +9 -0
- package/dist/resources/templates/workflow-sources/workflowDocs.mjs +520 -0
- package/dist/resources/templates/workflow-sources/workflowEditorOverrides.json +1 -0
- package/dist/resources/templates/workflows/collaborate.yaml +104 -0
- package/dist/resources/templates/workflows/do.yaml +82 -0
- package/dist/resources/templates/workflows/evaluate.yaml +111 -0
- package/dist/resources/templates/workflows/execute.yaml +142 -0
- package/dist/resources/templates/workflows/plan.yaml +112 -0
- package/dist/resources/templates/workflows/review.yaml +109 -0
- package/dist/runtime/capabilities.d.ts +8 -0
- package/dist/runtime/capabilities.js +16 -0
- package/dist/security/virusScan.d.ts +16 -0
- package/dist/security/virusScan.js +83 -0
- package/dist/server/auth.d.ts +51 -0
- package/dist/server/auth.js +266 -0
- package/dist/server/auth.test.d.ts +1 -0
- package/dist/server/auth.test.js +111 -0
- package/dist/server/buildInfo.d.ts +7 -0
- package/dist/server/buildInfo.js +100 -0
- package/dist/server/buildInfo.test.d.ts +1 -0
- package/dist/server/buildInfo.test.js +29 -0
- package/dist/server/cors.d.ts +7 -0
- package/dist/server/cors.js +76 -0
- package/dist/server/cors.test.d.ts +1 -0
- package/dist/server/cors.test.js +71 -0
- package/dist/server/email.d.ts +28 -0
- package/dist/server/email.js +138 -0
- package/dist/server/email.test.d.ts +1 -0
- package/dist/server/email.test.js +113 -0
- package/dist/server/index.cookieProxy.test.d.ts +1 -0
- package/dist/server/index.cookieProxy.test.js +19 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +757 -0
- package/dist/server/index.rateLimit.test.d.ts +1 -0
- package/dist/server/index.rateLimit.test.js +13 -0
- package/dist/server/index.test.d.ts +1 -0
- package/dist/server/index.test.js +19 -0
- package/dist/server/rateLimit.d.ts +29 -0
- package/dist/server/rateLimit.js +99 -0
- package/dist/server/rateLimit.test.d.ts +1 -0
- package/dist/server/rateLimit.test.js +107 -0
- package/dist/server/realtimeSync.auth.test.d.ts +1 -0
- package/dist/server/realtimeSync.auth.test.js +62 -0
- package/dist/server/realtimeSync.replay.test.d.ts +1 -0
- package/dist/server/realtimeSync.replay.test.js +192 -0
- package/dist/server/realtimeSync.workspaceIsolation.test.d.ts +1 -0
- package/dist/server/realtimeSync.workspaceIsolation.test.js +101 -0
- package/dist/server/realtimeSyncWs.d.ts +30 -0
- package/dist/server/realtimeSyncWs.js +257 -0
- package/dist/server/routes.billing.d.ts +15 -0
- package/dist/server/routes.billing.js +991 -0
- package/dist/server/routes.billing.test.d.ts +1 -0
- package/dist/server/routes.billing.test.js +387 -0
- package/dist/server/routes.d.ts +72 -0
- package/dist/server/routes.js +4820 -0
- package/dist/server/routes.sync.d.ts +17 -0
- package/dist/server/routes.sync.integration.test.d.ts +1 -0
- package/dist/server/routes.sync.integration.test.js +470 -0
- package/dist/server/routes.sync.js +1141 -0
- package/dist/server/routes.test.d.ts +1 -0
- package/dist/server/routes.test.js +4945 -0
- package/dist/server/runtimeMode.d.ts +4 -0
- package/dist/server/runtimeMode.js +25 -0
- package/dist/server/runtimeMode.test.d.ts +1 -0
- package/dist/server/runtimeMode.test.js +26 -0
- package/dist/server/securityHeaders.d.ts +3 -0
- package/dist/server/securityHeaders.js +25 -0
- package/dist/server/securityHeaders.test.d.ts +1 -0
- package/dist/server/securityHeaders.test.js +32 -0
- package/dist/server/smtpTransport.d.ts +21 -0
- package/dist/server/smtpTransport.js +11 -0
- package/dist/server/start.d.ts +1 -0
- package/dist/server/start.js +17 -0
- package/dist/services/formatTransformers.d.ts +29 -0
- package/dist/services/formatTransformers.js +56 -0
- package/dist/services/templateEngine.d.ts +46 -0
- package/dist/services/templateEngine.js +148 -0
- package/dist/shared/runtimeContract.d.ts +12 -0
- package/dist/shared/runtimeContract.js +23 -0
- package/dist/shared/runtimeContract.test.d.ts +1 -0
- package/dist/shared/runtimeContract.test.js +23 -0
- package/dist/soak/preflight.cli.d.ts +1 -0
- package/dist/soak/preflight.cli.js +28 -0
- package/dist/soak/preflight.d.ts +26 -0
- package/dist/soak/preflight.js +113 -0
- package/dist/soak/preflight.test.d.ts +1 -0
- package/dist/soak/preflight.test.js +39 -0
- package/dist/soak/syncSoakHarness.d.ts +6 -0
- package/dist/soak/syncSoakHarness.js +10 -0
- package/dist/storage/createDatabaseAdapter.d.ts +2 -0
- package/dist/storage/createDatabaseAdapter.js +9 -0
- package/dist/storage/databaseAdapter.d.ts +22 -0
- package/dist/storage/databaseAdapter.js +1 -0
- package/dist/storage/documentIntegrity.d.ts +28 -0
- package/dist/storage/documentIntegrity.js +103 -0
- package/dist/storage/documentPurge.d.ts +14 -0
- package/dist/storage/documentPurge.js +46 -0
- package/dist/storage/documentRegistry.d.ts +39 -0
- package/dist/storage/documentRegistry.js +115 -0
- package/dist/storage/integritySchedule.d.ts +17 -0
- package/dist/storage/integritySchedule.js +62 -0
- package/dist/storage/objectStorage.d.ts +20 -0
- package/dist/storage/objectStorage.js +15 -0
- package/dist/storage/objectStorageClient.d.ts +18 -0
- package/dist/storage/objectStorageClient.js +301 -0
- package/dist/storage/objectStorageConfig.d.ts +2 -0
- package/dist/storage/objectStorageConfig.js +45 -0
- package/dist/storage/postgresAdapter.d.ts +20 -0
- package/dist/storage/postgresAdapter.js +204 -0
- package/dist/storage/postgresWorker.d.ts +1 -0
- package/dist/storage/postgresWorker.js +110 -0
- package/dist/storage/providerConfig.d.ts +6 -0
- package/dist/storage/providerConfig.js +11 -0
- package/dist/storage/sqliteAdapter.d.ts +14 -0
- package/dist/storage/sqliteAdapter.js +28 -0
- package/dist/storage/taskAssetStore.d.ts +56 -0
- package/dist/storage/taskAssetStore.js +297 -0
- package/dist/sync/cloudSyncApi.d.ts +47 -0
- package/dist/sync/cloudSyncApi.js +138 -0
- package/dist/sync/cloudSyncApi.test.d.ts +1 -0
- package/dist/sync/cloudSyncApi.test.js +54 -0
- package/dist/sync/encryptionService.d.ts +11 -0
- package/dist/sync/encryptionService.js +61 -0
- package/dist/sync/encryptionService.test.d.ts +1 -0
- package/dist/sync/encryptionService.test.js +52 -0
- package/dist/sync/realtimeFeature.d.ts +6 -0
- package/dist/sync/realtimeFeature.js +20 -0
- package/dist/sync/realtimeFeature.test.d.ts +1 -0
- package/dist/sync/realtimeFeature.test.js +30 -0
- package/dist/sync/realtimeReconcile.d.ts +30 -0
- package/dist/sync/realtimeReconcile.js +90 -0
- package/dist/sync/realtimeReconcile.test.d.ts +1 -0
- package/dist/sync/realtimeReconcile.test.js +43 -0
- package/dist/sync/syncService.d.ts +96 -0
- package/dist/sync/syncService.js +423 -0
- package/dist/sync/syncService.test.d.ts +1 -0
- package/dist/sync/syncService.test.js +484 -0
- package/dist/sync/workspaceSyncModel.d.ts +61 -0
- package/dist/sync/workspaceSyncModel.js +136 -0
- package/dist/sync/workspaceSyncModel.test.d.ts +1 -0
- package/dist/sync/workspaceSyncModel.test.js +73 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +15 -0
- package/dist/types.d.ts +157 -0
- package/dist/types.js +41 -0
- package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
- package/dist/ui/assets/index-0W5vyCpn.css +1 -0
- package/dist/ui/assets/index-MCZuNNfn.js +23 -0
- package/dist/ui/assets/logo_white_01-0Vx-iIIv.png +0 -0
- package/dist/ui/assets/taskforce-BxLPokNB.png +0 -0
- package/dist/ui/assets/vendor-dnd-BI1K77C1.js +5 -0
- package/dist/ui/assets/vendor-icons-ZFG3SGwo.js +1 -0
- package/dist/ui/assets/vendor-markdown-CKYkQHfj.js +29 -0
- package/dist/ui/assets/vendor-react-DdIDsh7f.js +9 -0
- package/dist/ui/assets/vendor-router-BtiNU7Dl.js +3 -0
- package/dist/ui/branding/logos/logo_black_01.png +0 -0
- package/dist/ui/branding/logos/logo_black_02.png +0 -0
- package/dist/ui/branding/logos/logo_white_01.png +0 -0
- package/dist/ui/branding/logos/logo_white_02.png +0 -0
- package/dist/ui/favicon/android-chrome-192x192.png +0 -0
- package/dist/ui/favicon/android-chrome-512x512.png +0 -0
- package/dist/ui/favicon/apple-touch-icon.png +0 -0
- package/dist/ui/favicon/favicon-16x16.png +0 -0
- package/dist/ui/favicon/favicon-32x32.png +0 -0
- package/dist/ui/favicon/favicon.ico +0 -0
- package/dist/ui/favicon/favicon.png +0 -0
- package/dist/ui/favicon/site.webmanifest +1 -0
- package/dist/ui/fonts/RussoOne-Regular.ttf +0 -0
- package/dist/ui/images/taskforce.png +0 -0
- package/dist/ui/index.html +19 -0
- package/dist/utils/checklistMarkdown.d.ts +9 -0
- package/dist/utils/checklistMarkdown.js +46 -0
- package/dist/utils/constants.d.ts +21 -0
- package/dist/utils/constants.icons.test.d.ts +1 -0
- package/dist/utils/constants.icons.test.js +40 -0
- package/dist/utils/constants.js +100 -0
- package/dist/utils/contextFiles.d.ts +8 -0
- package/dist/utils/contextFiles.js +54 -0
- package/dist/utils/formatting.d.ts +5 -0
- package/dist/utils/formatting.js +30 -0
- package/dist/utils/planParser.d.ts +22 -0
- package/dist/utils/planParser.js +151 -0
- package/dist/utils/taskDragZones.d.ts +8 -0
- package/dist/utils/taskDragZones.js +14 -0
- package/dist/utils/taskDragZones.test.d.ts +1 -0
- package/dist/utils/taskDragZones.test.js +14 -0
- package/dist/utils/taskHierarchy.d.ts +4 -0
- package/dist/utils/taskHierarchy.js +69 -0
- package/dist/utils/taskHierarchy.test.d.ts +1 -0
- package/dist/utils/taskHierarchy.test.js +38 -0
- package/dist/utils/taskParenting.d.ts +3 -0
- package/dist/utils/taskParenting.js +24 -0
- package/dist/utils/taskParenting.test.d.ts +1 -0
- package/dist/utils/taskParenting.test.js +21 -0
- package/dist/utils/taskRelations.d.ts +6 -0
- package/dist/utils/taskRelations.js +24 -0
- package/dist/utils/taskRelations.test.d.ts +1 -0
- package/dist/utils/taskRelations.test.js +34 -0
- package/dist/utils/taskUtils.d.ts +2 -0
- package/dist/utils/taskUtils.js +20 -0
- package/dist/utils/taskforceApiClient.d.ts +7 -0
- package/dist/utils/taskforceApiClient.js +42 -0
- package/dist/utils/workspaceIdentity.d.ts +8 -0
- package/dist/utils/workspaceIdentity.js +47 -0
- package/dist/utils/workspaceIdentity.test.d.ts +1 -0
- package/dist/utils/workspaceIdentity.test.js +32 -0
- package/dist/utils/workspaceLifecycle.d.ts +26 -0
- package/dist/utils/workspaceLifecycle.js +69 -0
- package/dist/utils/workspaceLifecycle.test.d.ts +1 -0
- package/dist/utils/workspaceLifecycle.test.js +64 -0
- package/package.json +133 -0
- package/scripts/check-compat-boundaries.js +48 -0
- package/scripts/check-env.ts +24 -0
- package/scripts/check-localization-strings.mjs +49 -0
- package/scripts/check-runtime-boundaries.mjs +44 -0
- package/scripts/debug-global.mjs +34 -0
- package/scripts/debug-server.mjs +36 -0
- package/scripts/export-sqlite-to-postgres.mjs +125 -0
- package/scripts/generate-env-example.ts +8 -0
- package/scripts/generate-workflow-templates.mjs +134 -0
- package/scripts/mcp-stdio-adapter.mjs +160 -0
- package/scripts/postinstall.js +60 -0
- package/scripts/release-version-lib.mjs +88 -0
- package/scripts/release-version.mjs +72 -0
- package/scripts/run-dev-proxy.sh +49 -0
- package/scripts/run-e2e-realtime.sh +16 -0
- package/scripts/run-smoke.sh +23 -0
- package/scripts/run-soak.sh +29 -0
- package/scripts/test-global.js +143 -0
- package/scripts/update-homebrew-formula.sh +38 -0
- package/src/resources/templates/WORKFLOW_V2_POLICY.md +55 -0
- package/src/resources/templates/environments/aider.yaml +14 -0
- package/src/resources/templates/environments/antigravity.yaml +10 -0
- package/src/resources/templates/environments/claude.yaml +10 -0
- package/src/resources/templates/environments/cline.yaml +10 -0
- package/src/resources/templates/environments/codex.yaml +13 -0
- package/src/resources/templates/environments/copilot.yaml +10 -0
- package/src/resources/templates/environments/cursor.yaml +9 -0
- package/src/resources/templates/environments/gemini.yaml +9 -0
- package/src/resources/templates/environments/windsurf.yaml +10 -0
- package/src/resources/templates/workflow-sources/README.md +9 -0
- package/src/resources/templates/workflow-sources/workflowDocs.mjs +520 -0
- package/src/resources/templates/workflow-sources/workflowEditorOverrides.json +1 -0
- package/src/resources/templates/workflows/collaborate.yaml +104 -0
- package/src/resources/templates/workflows/do.yaml +82 -0
- package/src/resources/templates/workflows/evaluate.yaml +111 -0
- package/src/resources/templates/workflows/execute.yaml +142 -0
- package/src/resources/templates/workflows/plan.yaml +112 -0
- package/src/resources/templates/workflows/review.yaml +109 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
2
|
+
import { renderHook, act } from '@testing-library/react';
|
|
3
|
+
import { useWorkspaceSyncController } from './useWorkspaceSyncController';
|
|
4
|
+
vi.mock('../sync/cloudSyncApi', () => ({
|
|
5
|
+
bootstrapPushWorkspaceSnapshot: vi.fn(),
|
|
6
|
+
pullWorkspaceChanges: vi.fn(),
|
|
7
|
+
applyLocalWorkspaceChanges: vi.fn(),
|
|
8
|
+
handshakeWorkspace: vi.fn(),
|
|
9
|
+
provisionWorkspace: vi.fn()
|
|
10
|
+
}));
|
|
11
|
+
const makeInput = (overrides = {}) => ({
|
|
12
|
+
currentWorkspaceId: 'ws-test',
|
|
13
|
+
setWorkspaceSyncReady: vi.fn(),
|
|
14
|
+
setWorkspaceCloudHydrated: vi.fn(),
|
|
15
|
+
setWorkspaceCloudSyncEnabled: vi.fn(),
|
|
16
|
+
setWorkspaceSyncSourceOfTruth: vi.fn(),
|
|
17
|
+
setWorkspaceSyncOnboardingCompleted: vi.fn(),
|
|
18
|
+
setUserGlobalLastSyncedAt: vi.fn(),
|
|
19
|
+
setWorkspaceLastPullAt: vi.fn(),
|
|
20
|
+
setWorkspaceLastPushAt: vi.fn(),
|
|
21
|
+
...overrides
|
|
22
|
+
});
|
|
23
|
+
describe('useWorkspaceSyncController — tryAcquireWorkspacePullLease', () => {
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
localStorage.clear();
|
|
26
|
+
vi.useRealTimers();
|
|
27
|
+
vi.unstubAllGlobals();
|
|
28
|
+
});
|
|
29
|
+
it('returns true when navigator.locks is not available (e.g. SSR or old browser)', async () => {
|
|
30
|
+
// Simulate environment without locks API
|
|
31
|
+
vi.stubGlobal('navigator', { locks: undefined });
|
|
32
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
33
|
+
let acquired;
|
|
34
|
+
await act(async () => {
|
|
35
|
+
acquired = await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
36
|
+
});
|
|
37
|
+
expect(acquired).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it('uses localStorage lease fallback and returns false when another owner holds an active lease', async () => {
|
|
40
|
+
vi.stubGlobal('navigator', { locks: undefined });
|
|
41
|
+
const leaseKey = 'taskforce.sync.pullLease.v1.ws-test';
|
|
42
|
+
window.localStorage.setItem(leaseKey, JSON.stringify({
|
|
43
|
+
owner: 'other-tab',
|
|
44
|
+
acquiredAt: Date.now(),
|
|
45
|
+
expiresAt: Date.now() + 30_000
|
|
46
|
+
}));
|
|
47
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
48
|
+
let acquired;
|
|
49
|
+
await act(async () => {
|
|
50
|
+
acquired = await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
51
|
+
});
|
|
52
|
+
expect(acquired).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
it('acquires and releases localStorage lease fallback when locks API is unavailable', async () => {
|
|
55
|
+
vi.stubGlobal('navigator', { locks: undefined });
|
|
56
|
+
const leaseKey = 'taskforce.sync.pullLease.v1.ws-test';
|
|
57
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
58
|
+
let acquired;
|
|
59
|
+
await act(async () => {
|
|
60
|
+
acquired = await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
61
|
+
});
|
|
62
|
+
expect(acquired).toBe(true);
|
|
63
|
+
const stored = JSON.parse(String(window.localStorage.getItem(leaseKey) || '{}'));
|
|
64
|
+
expect(typeof stored.owner).toBe('string');
|
|
65
|
+
expect(Number(stored.expiresAt)).toBeGreaterThan(Date.now());
|
|
66
|
+
act(() => {
|
|
67
|
+
result.current.releaseWorkspacePullLease('ws-test');
|
|
68
|
+
});
|
|
69
|
+
expect(window.localStorage.getItem(leaseKey)).toBeNull();
|
|
70
|
+
});
|
|
71
|
+
it('returns false when another tab already holds the exclusive lock (cross-tab guard)', async () => {
|
|
72
|
+
// Simulate navigator.locks.request calling the callback with null (lock unavailable)
|
|
73
|
+
const mockRequest = vi.fn().mockImplementation((_name, _opts, callback) => {
|
|
74
|
+
// ifAvailable: true — lock not available, callback receives null
|
|
75
|
+
const p = Promise.resolve(callback(null));
|
|
76
|
+
return p;
|
|
77
|
+
});
|
|
78
|
+
vi.stubGlobal('navigator', { locks: { request: mockRequest } });
|
|
79
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
80
|
+
let acquired;
|
|
81
|
+
await act(async () => {
|
|
82
|
+
acquired = await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
83
|
+
});
|
|
84
|
+
expect(acquired).toBe(false);
|
|
85
|
+
expect(mockRequest).toHaveBeenCalledOnce();
|
|
86
|
+
expect(mockRequest.mock.calls[0][0]).toBe('taskforce.sync.pullLock.ws-test');
|
|
87
|
+
expect(mockRequest.mock.calls[0][1]).toMatchObject({ mode: 'exclusive', ifAvailable: true });
|
|
88
|
+
});
|
|
89
|
+
it('returns true when the lock is successfully acquired', async () => {
|
|
90
|
+
// Simulate navigator.locks.request calling the callback with a lock object
|
|
91
|
+
const mockRequest = vi.fn().mockImplementation((_name, _opts, callback) => {
|
|
92
|
+
// Call callback with a fake lock object; the callback returns a never-resolving promise
|
|
93
|
+
// to "hold" the lock — we just need to verify the outer promise resolved true
|
|
94
|
+
callback({ name: _name });
|
|
95
|
+
// Return a promise that stays pending (simulating lock held)
|
|
96
|
+
return new Promise(() => { });
|
|
97
|
+
});
|
|
98
|
+
vi.stubGlobal('navigator', { locks: { request: mockRequest } });
|
|
99
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
100
|
+
// We need a race because the lock-hold promise never resolves
|
|
101
|
+
let acquired;
|
|
102
|
+
await act(async () => {
|
|
103
|
+
const leasePromise = result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
104
|
+
// The inner Promise resolves(true) synchronously after callback is invoked
|
|
105
|
+
acquired = await leasePromise;
|
|
106
|
+
});
|
|
107
|
+
expect(acquired).toBe(true);
|
|
108
|
+
expect(mockRequest).toHaveBeenCalledOnce();
|
|
109
|
+
});
|
|
110
|
+
it('returns true on second call when the lock is already held by this tab', async () => {
|
|
111
|
+
// First call acquires the lock
|
|
112
|
+
const mockRequest = vi.fn().mockImplementation((_name, _opts, callback) => {
|
|
113
|
+
callback({ name: _name });
|
|
114
|
+
return new Promise(() => { });
|
|
115
|
+
});
|
|
116
|
+
vi.stubGlobal('navigator', { locks: { request: mockRequest } });
|
|
117
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
118
|
+
await act(async () => {
|
|
119
|
+
await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
120
|
+
});
|
|
121
|
+
// Second call should short-circuit without calling navigator.locks.request again
|
|
122
|
+
let secondAcquired;
|
|
123
|
+
await act(async () => {
|
|
124
|
+
secondAcquired = await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
125
|
+
});
|
|
126
|
+
expect(secondAcquired).toBe(true);
|
|
127
|
+
// navigator.locks.request should only have been called once (first acquisition)
|
|
128
|
+
expect(mockRequest).toHaveBeenCalledOnce();
|
|
129
|
+
});
|
|
130
|
+
it('does not treat a lock held for one workspace as acquired for another workspace', async () => {
|
|
131
|
+
const mockRequest = vi.fn()
|
|
132
|
+
.mockImplementationOnce((_name, _opts, callback) => {
|
|
133
|
+
callback({ name: _name });
|
|
134
|
+
return new Promise(() => { });
|
|
135
|
+
})
|
|
136
|
+
.mockImplementationOnce((_name, _opts, callback) => {
|
|
137
|
+
const p = Promise.resolve(callback(null));
|
|
138
|
+
return p;
|
|
139
|
+
});
|
|
140
|
+
vi.stubGlobal('navigator', { locks: { request: mockRequest } });
|
|
141
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
142
|
+
let firstAcquired;
|
|
143
|
+
let secondAcquired;
|
|
144
|
+
await act(async () => {
|
|
145
|
+
firstAcquired = await result.current.tryAcquireWorkspacePullLease('ws-a');
|
|
146
|
+
secondAcquired = await result.current.tryAcquireWorkspacePullLease('ws-b');
|
|
147
|
+
});
|
|
148
|
+
expect(firstAcquired).toBe(true);
|
|
149
|
+
expect(secondAcquired).toBe(false);
|
|
150
|
+
expect(mockRequest).toHaveBeenCalledTimes(1);
|
|
151
|
+
expect(mockRequest.mock.calls[0][0]).toBe('taskforce.sync.pullLock.ws-a');
|
|
152
|
+
});
|
|
153
|
+
it('releases the lock and allows re-acquisition after releaseWorkspacePullLease', async () => {
|
|
154
|
+
let resolveHold;
|
|
155
|
+
const mockRequest = vi.fn().mockImplementation((_name, _opts, callback) => {
|
|
156
|
+
callback({ name: _name });
|
|
157
|
+
return new Promise((resolve) => { resolveHold = resolve; });
|
|
158
|
+
});
|
|
159
|
+
vi.stubGlobal('navigator', { locks: { request: mockRequest } });
|
|
160
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput()));
|
|
161
|
+
await act(async () => {
|
|
162
|
+
await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
163
|
+
});
|
|
164
|
+
// Release the lock
|
|
165
|
+
act(() => {
|
|
166
|
+
result.current.releaseWorkspacePullLease('ws-test');
|
|
167
|
+
resolveHold(); // allow the lock-hold promise to settle
|
|
168
|
+
});
|
|
169
|
+
// Now try to acquire again — should call navigator.locks.request a second time
|
|
170
|
+
await act(async () => {
|
|
171
|
+
await result.current.tryAcquireWorkspacePullLease('ws-test');
|
|
172
|
+
});
|
|
173
|
+
expect(mockRequest).toHaveBeenCalledTimes(2);
|
|
174
|
+
});
|
|
175
|
+
it('resets in-flight push/pull refs when workspace changes', async () => {
|
|
176
|
+
let input = makeInput({ currentWorkspaceId: 'ws-a' });
|
|
177
|
+
const { result, rerender } = renderHook((props) => useWorkspaceSyncController(props), {
|
|
178
|
+
initialProps: input
|
|
179
|
+
});
|
|
180
|
+
act(() => {
|
|
181
|
+
result.current.workspacePushInFlightRef.current = true;
|
|
182
|
+
result.current.workspacePullInFlightRef.current = true;
|
|
183
|
+
});
|
|
184
|
+
input = makeInput({ currentWorkspaceId: 'ws-b' });
|
|
185
|
+
rerender(input);
|
|
186
|
+
expect(result.current.workspacePushInFlightRef.current).toBe(false);
|
|
187
|
+
expect(result.current.workspacePullInFlightRef.current).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
it('clears same-deadline cooldown when retry timer fires so scheduled pull is not self-blocked', async () => {
|
|
190
|
+
const { result } = renderHook(() => useWorkspaceSyncController(makeInput({ currentWorkspaceId: 'ws-cooldown' })));
|
|
191
|
+
const invokePull = vi.fn().mockResolvedValue(true);
|
|
192
|
+
let scheduledRetryCallback = null;
|
|
193
|
+
const setTimeoutSpy = vi.spyOn(window, 'setTimeout').mockImplementation(((callback) => {
|
|
194
|
+
scheduledRetryCallback = callback;
|
|
195
|
+
return 1;
|
|
196
|
+
}));
|
|
197
|
+
const clearTimeoutSpy = vi.spyOn(window, 'clearTimeout').mockImplementation((() => { }));
|
|
198
|
+
act(() => {
|
|
199
|
+
result.current.scheduleWorkspacePullRetry(invokePull, { minDelayMs: 250, workspaceId: 'ws-cooldown' });
|
|
200
|
+
});
|
|
201
|
+
const cooldownKey = 'taskforce.sync.pullCooldown.v1.ws-cooldown';
|
|
202
|
+
const before = JSON.parse(String(window.localStorage.getItem(cooldownKey) || '{}'));
|
|
203
|
+
expect(Number(before.nextAllowedAt)).toBeGreaterThan(Date.now());
|
|
204
|
+
expect(typeof scheduledRetryCallback).toBe('function');
|
|
205
|
+
act(() => {
|
|
206
|
+
scheduledRetryCallback?.();
|
|
207
|
+
});
|
|
208
|
+
expect(invokePull).toHaveBeenCalledTimes(1);
|
|
209
|
+
const after = JSON.parse(String(window.localStorage.getItem(cooldownKey) || '{}'));
|
|
210
|
+
expect(Number(after.nextAllowedAt)).toBeLessThanOrEqual(Date.now());
|
|
211
|
+
expect(result.current.isWorkspacePullCooldownActive('ws-cooldown')).toBe(false);
|
|
212
|
+
setTimeoutSpy.mockRestore();
|
|
213
|
+
clearTimeoutSpy.mockRestore();
|
|
214
|
+
});
|
|
215
|
+
it('keeps recordWorkspaceSyncFailure stable and dispatches to latest onFailureRecorded callback', () => {
|
|
216
|
+
const firstCallback = vi.fn();
|
|
217
|
+
let input = makeInput({ onFailureRecorded: firstCallback });
|
|
218
|
+
const { result, rerender } = renderHook((props) => useWorkspaceSyncController(props), {
|
|
219
|
+
initialProps: input
|
|
220
|
+
});
|
|
221
|
+
const recordBeforeRerender = result.current.recordWorkspaceSyncFailure;
|
|
222
|
+
act(() => {
|
|
223
|
+
result.current.recordWorkspaceSyncFailure('pull', 503);
|
|
224
|
+
});
|
|
225
|
+
expect(firstCallback).toHaveBeenCalledWith('pull', 503);
|
|
226
|
+
const secondCallback = vi.fn();
|
|
227
|
+
input = makeInput({ onFailureRecorded: secondCallback });
|
|
228
|
+
rerender(input);
|
|
229
|
+
const recordAfterRerender = result.current.recordWorkspaceSyncFailure;
|
|
230
|
+
expect(recordAfterRerender).toBe(recordBeforeRerender);
|
|
231
|
+
act(() => {
|
|
232
|
+
result.current.recordWorkspaceSyncFailure('handshake', 429);
|
|
233
|
+
});
|
|
234
|
+
expect(secondCallback).toHaveBeenCalledWith('handshake', 429);
|
|
235
|
+
});
|
|
236
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taskforce Manager
|
|
3
|
+
*
|
|
4
|
+
* A decoupled, reusable collaborative task manager.
|
|
5
|
+
*/
|
|
6
|
+
export { Taskforce } from './Taskforce';
|
|
7
|
+
export { TaskforceCore } from './TaskforceCore';
|
|
8
|
+
export { TaskforceWidget } from './TaskforceWidget';
|
|
9
|
+
export { StandaloneLayout as TaskforceStandaloneLayout } from './components/views/StandaloneLayout';
|
|
10
|
+
export type { TaskforceConfig, TaskItem } from './types';
|
|
11
|
+
export { DEFAULT_CONFIG } from './types';
|
|
12
|
+
export { submitTask, getPendingTasks, clearPendingTasks, exportTasksAsMarkdown, copyTasksToClipboard } from './api';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taskforce Manager
|
|
3
|
+
*
|
|
4
|
+
* A decoupled, reusable collaborative task manager.
|
|
5
|
+
*/
|
|
6
|
+
export { Taskforce } from './Taskforce';
|
|
7
|
+
export { TaskforceCore } from './TaskforceCore';
|
|
8
|
+
export { TaskforceWidget } from './TaskforceWidget';
|
|
9
|
+
export { StandaloneLayout as TaskforceStandaloneLayout } from './components/views/StandaloneLayout';
|
|
10
|
+
export { DEFAULT_CONFIG } from './types';
|
|
11
|
+
export { submitTask, getPendingTasks, clearPendingTasks, exportTasksAsMarkdown, copyTasksToClipboard } from './api';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const SUPPORTED_LOCALES: readonly ["en-US", "es-419", "pt-BR"];
|
|
2
|
+
export type SupportedLocale = typeof SUPPORTED_LOCALES[number];
|
|
3
|
+
export declare function isSupportedLocale(locale: string): locale is SupportedLocale;
|
|
4
|
+
export declare function getLocale(): SupportedLocale;
|
|
5
|
+
export declare function getSupportedLocales(): SupportedLocale[];
|
|
6
|
+
export declare function setLocale(locale: string): SupportedLocale;
|
|
7
|
+
export declare function initializeLocale(preferredLocale?: string): SupportedLocale;
|
|
8
|
+
export declare function t(key: string, params?: Record<string, string | number>): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { enUS } from './locales/en-US';
|
|
2
|
+
import { es419 } from './locales/es-419';
|
|
3
|
+
import { ptBR } from './locales/pt-BR';
|
|
4
|
+
export const SUPPORTED_LOCALES = ['en-US', 'es-419', 'pt-BR'];
|
|
5
|
+
const DEFAULT_LOCALE = 'en-US';
|
|
6
|
+
const CATALOGS = {
|
|
7
|
+
'en-US': enUS,
|
|
8
|
+
'es-419': es419,
|
|
9
|
+
'pt-BR': ptBR
|
|
10
|
+
};
|
|
11
|
+
const BASE_FALLBACK = {
|
|
12
|
+
en: 'en-US',
|
|
13
|
+
es: 'es-419',
|
|
14
|
+
pt: 'pt-BR'
|
|
15
|
+
};
|
|
16
|
+
let currentLocale = DEFAULT_LOCALE;
|
|
17
|
+
function toPathParts(key) {
|
|
18
|
+
return key.split('.').filter(Boolean);
|
|
19
|
+
}
|
|
20
|
+
function getByPath(source, path) {
|
|
21
|
+
let cursor = source;
|
|
22
|
+
for (const part of path) {
|
|
23
|
+
if (!cursor || typeof cursor !== 'object')
|
|
24
|
+
return undefined;
|
|
25
|
+
cursor = cursor[part];
|
|
26
|
+
}
|
|
27
|
+
return typeof cursor === 'string' ? cursor : undefined;
|
|
28
|
+
}
|
|
29
|
+
function resolveLocale(input) {
|
|
30
|
+
if (!input)
|
|
31
|
+
return DEFAULT_LOCALE;
|
|
32
|
+
const exact = SUPPORTED_LOCALES.find((locale) => locale.toLowerCase() === input.toLowerCase());
|
|
33
|
+
if (exact)
|
|
34
|
+
return exact;
|
|
35
|
+
const base = input.split('-')[0]?.toLowerCase() || '';
|
|
36
|
+
return BASE_FALLBACK[base] || DEFAULT_LOCALE;
|
|
37
|
+
}
|
|
38
|
+
function formatTemplate(template, params) {
|
|
39
|
+
if (!params)
|
|
40
|
+
return template;
|
|
41
|
+
return template.replace(/\{([^}]+)\}/g, (_m, key) => {
|
|
42
|
+
const value = params[key];
|
|
43
|
+
return value === undefined || value === null ? '' : String(value);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function isSupportedLocale(locale) {
|
|
47
|
+
return SUPPORTED_LOCALES.includes(locale);
|
|
48
|
+
}
|
|
49
|
+
export function getLocale() {
|
|
50
|
+
return currentLocale;
|
|
51
|
+
}
|
|
52
|
+
export function getSupportedLocales() {
|
|
53
|
+
return [...SUPPORTED_LOCALES];
|
|
54
|
+
}
|
|
55
|
+
export function setLocale(locale) {
|
|
56
|
+
const resolved = resolveLocale(locale);
|
|
57
|
+
currentLocale = resolved;
|
|
58
|
+
return resolved;
|
|
59
|
+
}
|
|
60
|
+
export function initializeLocale(preferredLocale) {
|
|
61
|
+
const fromBrowser = typeof navigator !== 'undefined' ? navigator.language : null;
|
|
62
|
+
currentLocale = resolveLocale(preferredLocale || fromBrowser);
|
|
63
|
+
return currentLocale;
|
|
64
|
+
}
|
|
65
|
+
export function t(key, params) {
|
|
66
|
+
const path = toPathParts(key);
|
|
67
|
+
const current = getByPath(CATALOGS[currentLocale], path);
|
|
68
|
+
if (current)
|
|
69
|
+
return formatTemplate(current, params);
|
|
70
|
+
const base = currentLocale.split('-')[0]?.toLowerCase() || '';
|
|
71
|
+
const baseFallback = BASE_FALLBACK[base];
|
|
72
|
+
if (baseFallback && baseFallback !== currentLocale) {
|
|
73
|
+
const fromBase = getByPath(CATALOGS[baseFallback], path);
|
|
74
|
+
if (fromBase)
|
|
75
|
+
return formatTemplate(fromBase, params);
|
|
76
|
+
}
|
|
77
|
+
const fromDefault = getByPath(CATALOGS[DEFAULT_LOCALE], path);
|
|
78
|
+
if (fromDefault)
|
|
79
|
+
return formatTemplate(fromDefault, params);
|
|
80
|
+
return key;
|
|
81
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
export interface MessageCatalog {
|
|
2
|
+
taskForm: {
|
|
3
|
+
commentsSectionTitle: string;
|
|
4
|
+
hideComments: string;
|
|
5
|
+
showComments: string;
|
|
6
|
+
noComments: string;
|
|
7
|
+
you: string;
|
|
8
|
+
commentPlaceholder: string;
|
|
9
|
+
scheduledLabel: string;
|
|
10
|
+
dueLabel: string;
|
|
11
|
+
createdLabel: string;
|
|
12
|
+
updatedLabel: string;
|
|
13
|
+
completedLabel: string;
|
|
14
|
+
emptyValue: string;
|
|
15
|
+
parentCannotSchedule: string;
|
|
16
|
+
dueBeforeScheduled: string;
|
|
17
|
+
overdue: string;
|
|
18
|
+
};
|
|
19
|
+
schedule: {
|
|
20
|
+
completedOnlyPastSchedule: string;
|
|
21
|
+
noUnscheduledLeafTasks: string;
|
|
22
|
+
};
|
|
23
|
+
taskList: {
|
|
24
|
+
searchPlaceholder: string;
|
|
25
|
+
clearSearchTitle: string;
|
|
26
|
+
categoryLabel: string;
|
|
27
|
+
typeLabel: string;
|
|
28
|
+
priorityLabel: string;
|
|
29
|
+
statusLabel: string;
|
|
30
|
+
assigneeLabel: string;
|
|
31
|
+
sortByLabel: string;
|
|
32
|
+
sortCreated: string;
|
|
33
|
+
sortUpdated: string;
|
|
34
|
+
sortPriority: string;
|
|
35
|
+
sortDirectionDescTitle: string;
|
|
36
|
+
sortDirectionAscTitle: string;
|
|
37
|
+
resetFiltersTitle: string;
|
|
38
|
+
archiveAllTitle: string;
|
|
39
|
+
noTasksToArchiveTitle: string;
|
|
40
|
+
archiveFinished: string;
|
|
41
|
+
linksLabel: string;
|
|
42
|
+
linksAll: string;
|
|
43
|
+
linksParents: string;
|
|
44
|
+
linksLinked: string;
|
|
45
|
+
linksUnlinked: string;
|
|
46
|
+
includeArchive: string;
|
|
47
|
+
noMatchingTasks: string;
|
|
48
|
+
noActiveTasks: string;
|
|
49
|
+
addTaskToCategoryTitle: string;
|
|
50
|
+
};
|
|
51
|
+
actionHeader: {
|
|
52
|
+
blockedByActiveChildren: string;
|
|
53
|
+
confirmCascadeComplete: string;
|
|
54
|
+
confirmCascadeCancel: string;
|
|
55
|
+
confirmCascadeArchive: string;
|
|
56
|
+
saveChangesTitle: string;
|
|
57
|
+
update: string;
|
|
58
|
+
copyTaskIdTitle: string;
|
|
59
|
+
startWorking: string;
|
|
60
|
+
stopWorking: string;
|
|
61
|
+
unlockAndContinue: string;
|
|
62
|
+
readyForReview: string;
|
|
63
|
+
markComplete: string;
|
|
64
|
+
unmarkComplete: string;
|
|
65
|
+
cancelTask: string;
|
|
66
|
+
unmarkCancelled: string;
|
|
67
|
+
archiveNow: string;
|
|
68
|
+
completeTaskToArchive: string;
|
|
69
|
+
clearFormTitle: string;
|
|
70
|
+
clear: string;
|
|
71
|
+
addTaskTitle: string;
|
|
72
|
+
addTask: string;
|
|
73
|
+
};
|
|
74
|
+
standalone: {
|
|
75
|
+
searchPlaceholder: string;
|
|
76
|
+
clearSearchTitle: string;
|
|
77
|
+
sortLabel: string;
|
|
78
|
+
sortCreated: string;
|
|
79
|
+
sortUpdated: string;
|
|
80
|
+
sortPriority: string;
|
|
81
|
+
sortComplexity: string;
|
|
82
|
+
sortDirectionDescTitle: string;
|
|
83
|
+
sortDirectionAscTitle: string;
|
|
84
|
+
groupLabel: string;
|
|
85
|
+
groupCategory: string;
|
|
86
|
+
groupType: string;
|
|
87
|
+
groupPriority: string;
|
|
88
|
+
groupComplexity: string;
|
|
89
|
+
groupApproach: string;
|
|
90
|
+
groupAssignee: string;
|
|
91
|
+
groupStatus: string;
|
|
92
|
+
groupHierarchy: string;
|
|
93
|
+
groupSchedule: string;
|
|
94
|
+
showEmptyColumns: string;
|
|
95
|
+
compressEmptyColumns: string;
|
|
96
|
+
hideEmptyColumns: string;
|
|
97
|
+
expandCards: string;
|
|
98
|
+
compressCards: string;
|
|
99
|
+
exitZenMode: string;
|
|
100
|
+
enterZenMode: string;
|
|
101
|
+
toggleFilters: string;
|
|
102
|
+
addTask: string;
|
|
103
|
+
helpTutorial: string;
|
|
104
|
+
settings: string;
|
|
105
|
+
filtersCaps: string;
|
|
106
|
+
categoryLabel: string;
|
|
107
|
+
typeLabel: string;
|
|
108
|
+
priorityLabel: string;
|
|
109
|
+
statusLabel: string;
|
|
110
|
+
assigneeLabel: string;
|
|
111
|
+
linksLabel: string;
|
|
112
|
+
chooseLinksTitle: string;
|
|
113
|
+
linksAll: string;
|
|
114
|
+
linksParents: string;
|
|
115
|
+
linksLinked: string;
|
|
116
|
+
linksUnlinked: string;
|
|
117
|
+
includeArchiveTitle: string;
|
|
118
|
+
includeArchive: string;
|
|
119
|
+
clearFilters: string;
|
|
120
|
+
noTasksMatchFilters: string;
|
|
121
|
+
showingWithLinksHint: string;
|
|
122
|
+
visibleActiveTasksTitle: string;
|
|
123
|
+
totalActiveTasksTitle: string;
|
|
124
|
+
};
|
|
125
|
+
setup: {
|
|
126
|
+
headingCheckFailed: string;
|
|
127
|
+
headingGlobalRequired: string;
|
|
128
|
+
headingWorkspaceRequired: string;
|
|
129
|
+
subtitleUnreadable: string;
|
|
130
|
+
subtitleGlobalRequired: string;
|
|
131
|
+
subtitleWorkspaceRequired: string;
|
|
132
|
+
runtimeLabel: string;
|
|
133
|
+
workspaceTermProject: string;
|
|
134
|
+
workspaceTermMission: string;
|
|
135
|
+
coreModeOption: string;
|
|
136
|
+
operationsModeOption: string;
|
|
137
|
+
workspaceNamePlaceholder: string;
|
|
138
|
+
workspaceDescriptionPlaceholder: string;
|
|
139
|
+
saving: string;
|
|
140
|
+
saveGlobalSetup: string;
|
|
141
|
+
saveWorkspaceSetup: string;
|
|
142
|
+
globalSetupSaved: string;
|
|
143
|
+
workspaceSetupSaved: string;
|
|
144
|
+
saveFailedWithStatus: string;
|
|
145
|
+
saveFailed: string;
|
|
146
|
+
saveWorkspaceFailed: string;
|
|
147
|
+
retrySetupCheck: string;
|
|
148
|
+
signOut: string;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export declare const enUS: MessageCatalog;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export const enUS = {
|
|
2
|
+
taskForm: {
|
|
3
|
+
commentsSectionTitle: 'Activity & Comments',
|
|
4
|
+
hideComments: 'Hide Comments',
|
|
5
|
+
showComments: 'Show Comments',
|
|
6
|
+
noComments: 'No comments yet. Start the conversation!',
|
|
7
|
+
you: 'You',
|
|
8
|
+
commentPlaceholder: 'Type a comment...',
|
|
9
|
+
scheduledLabel: 'Scheduled:',
|
|
10
|
+
dueLabel: 'Due:',
|
|
11
|
+
createdLabel: 'Created:',
|
|
12
|
+
updatedLabel: 'Updated:',
|
|
13
|
+
completedLabel: 'Completed:',
|
|
14
|
+
emptyValue: '—',
|
|
15
|
+
parentCannotSchedule: 'Parent tasks cannot be scheduled. Schedule leaf tasks instead.',
|
|
16
|
+
dueBeforeScheduled: 'Due date is before scheduled date.',
|
|
17
|
+
overdue: 'This task is overdue.'
|
|
18
|
+
},
|
|
19
|
+
schedule: {
|
|
20
|
+
completedOnlyPastSchedule: 'Only completed work can be scheduled in the past.',
|
|
21
|
+
noUnscheduledLeafTasks: 'No unscheduled leaf tasks found under "{parentTitle}".'
|
|
22
|
+
},
|
|
23
|
+
taskList: {
|
|
24
|
+
searchPlaceholder: 'Search tasks...',
|
|
25
|
+
clearSearchTitle: 'Clear search',
|
|
26
|
+
categoryLabel: 'Category',
|
|
27
|
+
typeLabel: 'Type',
|
|
28
|
+
priorityLabel: 'Priority',
|
|
29
|
+
statusLabel: 'Status',
|
|
30
|
+
assigneeLabel: 'Assignee',
|
|
31
|
+
sortByLabel: 'Sort By:',
|
|
32
|
+
sortCreated: 'Created',
|
|
33
|
+
sortUpdated: 'Updated',
|
|
34
|
+
sortPriority: 'Priority',
|
|
35
|
+
sortDirectionDescTitle: 'Sort: Last First',
|
|
36
|
+
sortDirectionAscTitle: 'Sort: First First',
|
|
37
|
+
resetFiltersTitle: 'Reset all filters',
|
|
38
|
+
archiveAllTitle: 'Archive all completed and cancelled tasks',
|
|
39
|
+
noTasksToArchiveTitle: 'No tasks to archive',
|
|
40
|
+
archiveFinished: 'Archive Finished',
|
|
41
|
+
linksLabel: 'Links',
|
|
42
|
+
linksAll: 'All',
|
|
43
|
+
linksParents: 'Parents',
|
|
44
|
+
linksLinked: 'Linked',
|
|
45
|
+
linksUnlinked: 'Unlinked',
|
|
46
|
+
includeArchive: 'Include Archive',
|
|
47
|
+
noMatchingTasks: 'No matching tasks',
|
|
48
|
+
noActiveTasks: 'No active tasks',
|
|
49
|
+
addTaskToCategoryTitle: 'Add task to {category}'
|
|
50
|
+
},
|
|
51
|
+
actionHeader: {
|
|
52
|
+
blockedByActiveChildren: 'Complete or cancel all direct child tasks first',
|
|
53
|
+
confirmCascadeComplete: 'This parent task has {count} active child task(s). Also mark all child tasks as complete?',
|
|
54
|
+
confirmCascadeCancel: 'This parent task has {count} active child task(s). Also mark all child tasks as cancelled?',
|
|
55
|
+
confirmCascadeArchive: 'This parent task has {count} child task(s). Also archive all child tasks?',
|
|
56
|
+
saveChangesTitle: 'Save Changes',
|
|
57
|
+
update: 'Update',
|
|
58
|
+
copyTaskIdTitle: 'Click to copy Task ID',
|
|
59
|
+
startWorking: 'Start Working',
|
|
60
|
+
stopWorking: 'Stop Working',
|
|
61
|
+
unlockAndContinue: 'Unlock & Continue Work',
|
|
62
|
+
readyForReview: 'Ready for Review',
|
|
63
|
+
markComplete: 'Mark Complete',
|
|
64
|
+
unmarkComplete: 'Unmark Complete',
|
|
65
|
+
cancelTask: 'Cancel Task',
|
|
66
|
+
unmarkCancelled: 'Unmark Cancelled',
|
|
67
|
+
archiveNow: 'Archive Now',
|
|
68
|
+
completeTaskToArchive: 'Complete task to archive',
|
|
69
|
+
clearFormTitle: 'Clear Form',
|
|
70
|
+
clear: 'Clear',
|
|
71
|
+
addTaskTitle: 'Add Task',
|
|
72
|
+
addTask: 'Add Task'
|
|
73
|
+
},
|
|
74
|
+
standalone: {
|
|
75
|
+
searchPlaceholder: 'Search tasks...',
|
|
76
|
+
clearSearchTitle: 'Clear search',
|
|
77
|
+
sortLabel: 'Sort:',
|
|
78
|
+
sortCreated: 'Created',
|
|
79
|
+
sortUpdated: 'Updated',
|
|
80
|
+
sortPriority: 'Priority',
|
|
81
|
+
sortComplexity: 'Complexity',
|
|
82
|
+
sortDirectionDescTitle: 'Sort: Last First',
|
|
83
|
+
sortDirectionAscTitle: 'Sort: First First',
|
|
84
|
+
groupLabel: 'Group:',
|
|
85
|
+
groupCategory: 'Category',
|
|
86
|
+
groupType: 'Type',
|
|
87
|
+
groupPriority: 'Priority',
|
|
88
|
+
groupComplexity: 'Complexity',
|
|
89
|
+
groupApproach: 'Approach',
|
|
90
|
+
groupAssignee: 'Assignee',
|
|
91
|
+
groupStatus: 'Status',
|
|
92
|
+
groupHierarchy: 'Hierarchy',
|
|
93
|
+
groupSchedule: 'Schedule',
|
|
94
|
+
showEmptyColumns: 'Show Empty Columns',
|
|
95
|
+
compressEmptyColumns: 'Compress Empty Columns',
|
|
96
|
+
hideEmptyColumns: 'Hide Empty Columns',
|
|
97
|
+
expandCards: 'Expand Cards',
|
|
98
|
+
compressCards: 'Compress Cards',
|
|
99
|
+
exitZenMode: 'Exit Zen Mode',
|
|
100
|
+
enterZenMode: 'Enter Zen Mode',
|
|
101
|
+
toggleFilters: 'Toggle Filters',
|
|
102
|
+
addTask: 'Add Task',
|
|
103
|
+
helpTutorial: 'Help / Tutorial',
|
|
104
|
+
settings: 'Settings',
|
|
105
|
+
filtersCaps: 'FILTERS:',
|
|
106
|
+
categoryLabel: 'Category',
|
|
107
|
+
typeLabel: 'Type',
|
|
108
|
+
priorityLabel: 'Priority',
|
|
109
|
+
statusLabel: 'Status',
|
|
110
|
+
assigneeLabel: 'Assignee',
|
|
111
|
+
linksLabel: 'Links:',
|
|
112
|
+
chooseLinksTitle: 'Choose which linked tasks are shown',
|
|
113
|
+
linksAll: 'All',
|
|
114
|
+
linksParents: 'Parents',
|
|
115
|
+
linksLinked: 'Linked',
|
|
116
|
+
linksUnlinked: 'Unlinked',
|
|
117
|
+
includeArchiveTitle: 'Include archived tasks',
|
|
118
|
+
includeArchive: 'Include Archive',
|
|
119
|
+
clearFilters: 'Clear Filters',
|
|
120
|
+
noTasksMatchFilters: 'No tasks match current filters.',
|
|
121
|
+
showingWithLinksHint: 'Showing: {parentFilterLabel}. Switch Links to All or clear filters.',
|
|
122
|
+
visibleActiveTasksTitle: 'Visible active tasks / total active tasks',
|
|
123
|
+
totalActiveTasksTitle: 'Total active tasks'
|
|
124
|
+
},
|
|
125
|
+
setup: {
|
|
126
|
+
headingCheckFailed: 'Setup Check Failed',
|
|
127
|
+
headingGlobalRequired: 'Global Setup Required',
|
|
128
|
+
headingWorkspaceRequired: 'Workspace Setup Required',
|
|
129
|
+
subtitleUnreadable: 'Taskforce could not read setup state. Retry to continue.',
|
|
130
|
+
subtitleGlobalRequired: 'Choose your default operating mode to continue.',
|
|
131
|
+
subtitleWorkspaceRequired: 'Set up your workspace profile to continue.',
|
|
132
|
+
runtimeLabel: 'Runtime',
|
|
133
|
+
workspaceTermProject: 'Project',
|
|
134
|
+
workspaceTermMission: 'Mission',
|
|
135
|
+
coreModeOption: 'Core Mode: {workspaceLabel} planning defaults',
|
|
136
|
+
operationsModeOption: 'Operations Mode: Mission-first terminology and flows',
|
|
137
|
+
workspaceNamePlaceholder: '{workspaceLabel} name',
|
|
138
|
+
workspaceDescriptionPlaceholder: '{workspaceLabel} description (optional)',
|
|
139
|
+
saving: 'Saving...',
|
|
140
|
+
saveGlobalSetup: 'Save Global Setup',
|
|
141
|
+
saveWorkspaceSetup: 'Save {workspaceLabel} Setup',
|
|
142
|
+
globalSetupSaved: 'Global setup saved.',
|
|
143
|
+
workspaceSetupSaved: '{workspaceLabel} setup saved.',
|
|
144
|
+
saveFailedWithStatus: 'Failed to save setup ({status})',
|
|
145
|
+
saveFailed: 'Failed to save setup.',
|
|
146
|
+
saveWorkspaceFailed: 'Failed to save workspace profile.',
|
|
147
|
+
retrySetupCheck: 'Retry Setup Check',
|
|
148
|
+
signOut: 'Sign Out'
|
|
149
|
+
}
|
|
150
|
+
};
|