@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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { Readable } from 'stream';
|
|
3
|
+
import Database from 'better-sqlite3';
|
|
4
|
+
import { registerBillingRoutes } from './routes.billing';
|
|
5
|
+
const mockConstructEvent = vi.fn();
|
|
6
|
+
const mockPricesList = vi.fn(async () => ({ data: [], has_more: false }));
|
|
7
|
+
const mockCheckoutCreate = vi.fn(async () => ({ id: 'cs_test', url: 'https://example.test/checkout' }));
|
|
8
|
+
const mockPortalCreate = vi.fn(async () => ({ id: 'bps_test', url: 'https://example.test/portal' }));
|
|
9
|
+
const mockSubscriptionCancel = vi.fn(async () => ({ id: 'sub_test', status: 'canceled' }));
|
|
10
|
+
vi.mock('stripe', () => ({
|
|
11
|
+
default: class StripeMock {
|
|
12
|
+
webhooks = {
|
|
13
|
+
constructEvent: mockConstructEvent
|
|
14
|
+
};
|
|
15
|
+
prices = {
|
|
16
|
+
list: mockPricesList
|
|
17
|
+
};
|
|
18
|
+
checkout = {
|
|
19
|
+
sessions: {
|
|
20
|
+
create: mockCheckoutCreate
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
billingPortal = {
|
|
24
|
+
sessions: {
|
|
25
|
+
create: mockPortalCreate
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
subscriptions = {
|
|
29
|
+
cancel: mockSubscriptionCancel
|
|
30
|
+
};
|
|
31
|
+
constructor(_apiKey) { }
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
function createMockReq(body, headers = {}) {
|
|
35
|
+
const req = Readable.from([Buffer.from(body, 'utf8')]);
|
|
36
|
+
req.headers = headers;
|
|
37
|
+
return req;
|
|
38
|
+
}
|
|
39
|
+
function createMockRes() {
|
|
40
|
+
const response = {
|
|
41
|
+
statusCode: 200,
|
|
42
|
+
headers: {},
|
|
43
|
+
body: '',
|
|
44
|
+
writeHead: vi.fn((statusCode, headers) => {
|
|
45
|
+
response.statusCode = statusCode;
|
|
46
|
+
response.headers = headers || {};
|
|
47
|
+
return response;
|
|
48
|
+
}),
|
|
49
|
+
end: vi.fn((payload) => {
|
|
50
|
+
response.body = String(payload || '');
|
|
51
|
+
return response;
|
|
52
|
+
})
|
|
53
|
+
};
|
|
54
|
+
return response;
|
|
55
|
+
}
|
|
56
|
+
function setupBillingSchema(db) {
|
|
57
|
+
db.exec(`
|
|
58
|
+
CREATE TABLE user_billing (
|
|
59
|
+
user_id TEXT PRIMARY KEY,
|
|
60
|
+
tenant_id TEXT NOT NULL,
|
|
61
|
+
stripe_customer_id TEXT,
|
|
62
|
+
stripe_subscription_id TEXT,
|
|
63
|
+
stripe_price_id TEXT,
|
|
64
|
+
stripe_status TEXT,
|
|
65
|
+
tier TEXT NOT NULL DEFAULT 'free',
|
|
66
|
+
billing_interval TEXT,
|
|
67
|
+
entitlement_state TEXT NOT NULL DEFAULT 'free',
|
|
68
|
+
trial_end TEXT,
|
|
69
|
+
current_period_end TEXT,
|
|
70
|
+
effective_until TEXT,
|
|
71
|
+
created_at TEXT NOT NULL,
|
|
72
|
+
updated_at TEXT NOT NULL
|
|
73
|
+
);
|
|
74
|
+
CREATE TABLE stripe_webhook_events (
|
|
75
|
+
event_id TEXT PRIMARY KEY,
|
|
76
|
+
tenant_id TEXT NOT NULL,
|
|
77
|
+
event_type TEXT NOT NULL,
|
|
78
|
+
processed_at TEXT NOT NULL
|
|
79
|
+
);
|
|
80
|
+
CREATE TABLE stripe_webhook_failures (
|
|
81
|
+
id TEXT PRIMARY KEY,
|
|
82
|
+
tenant_id TEXT NOT NULL,
|
|
83
|
+
event_id TEXT NOT NULL,
|
|
84
|
+
event_type TEXT,
|
|
85
|
+
reason TEXT NOT NULL,
|
|
86
|
+
payload_excerpt TEXT,
|
|
87
|
+
purge_after TEXT NOT NULL,
|
|
88
|
+
created_at TEXT NOT NULL
|
|
89
|
+
);
|
|
90
|
+
CREATE TABLE billing_price_mappings (
|
|
91
|
+
tenant_id TEXT NOT NULL,
|
|
92
|
+
plan_version_id TEXT NOT NULL,
|
|
93
|
+
billing_interval TEXT NOT NULL,
|
|
94
|
+
stripe_price_id TEXT NOT NULL,
|
|
95
|
+
active INTEGER NOT NULL DEFAULT 1,
|
|
96
|
+
created_at TEXT NOT NULL,
|
|
97
|
+
updated_at TEXT NOT NULL,
|
|
98
|
+
PRIMARY KEY (tenant_id, stripe_price_id)
|
|
99
|
+
);
|
|
100
|
+
CREATE TABLE plan_versions (
|
|
101
|
+
plan_version_id TEXT PRIMARY KEY,
|
|
102
|
+
tenant_id TEXT NOT NULL,
|
|
103
|
+
plan_id TEXT NOT NULL,
|
|
104
|
+
version_number INTEGER NOT NULL,
|
|
105
|
+
is_default INTEGER NOT NULL DEFAULT 0,
|
|
106
|
+
seat_limit INTEGER,
|
|
107
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
108
|
+
created_at TEXT NOT NULL,
|
|
109
|
+
updated_at TEXT NOT NULL
|
|
110
|
+
);
|
|
111
|
+
CREATE TABLE account_entitlements (
|
|
112
|
+
account_id TEXT PRIMARY KEY,
|
|
113
|
+
tenant_id TEXT NOT NULL,
|
|
114
|
+
plan_version_id TEXT NOT NULL,
|
|
115
|
+
entitlement_state TEXT NOT NULL DEFAULT 'active',
|
|
116
|
+
effective_at TEXT,
|
|
117
|
+
effective_until TEXT,
|
|
118
|
+
updated_by TEXT,
|
|
119
|
+
created_at TEXT NOT NULL,
|
|
120
|
+
updated_at TEXT NOT NULL
|
|
121
|
+
);
|
|
122
|
+
CREATE TABLE system_settings (
|
|
123
|
+
tenant_id TEXT NOT NULL,
|
|
124
|
+
settings_key TEXT NOT NULL,
|
|
125
|
+
payload TEXT,
|
|
126
|
+
updated_at TEXT NOT NULL,
|
|
127
|
+
PRIMARY KEY (tenant_id, settings_key)
|
|
128
|
+
);
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
function buildBillingRouteHandlers(db, opts) {
|
|
132
|
+
const routes = new Map();
|
|
133
|
+
const tenantId = 'default';
|
|
134
|
+
const core = {
|
|
135
|
+
getDatabaseAdapter: () => db,
|
|
136
|
+
getTenantId: () => tenantId,
|
|
137
|
+
createUserBillingRecord: (userId) => {
|
|
138
|
+
const now = new Date().toISOString();
|
|
139
|
+
db.prepare(`
|
|
140
|
+
INSERT INTO user_billing (
|
|
141
|
+
user_id, tenant_id, tier, entitlement_state, created_at, updated_at
|
|
142
|
+
) VALUES (?, ?, 'free', 'free', ?, ?)
|
|
143
|
+
ON CONFLICT (user_id) DO NOTHING
|
|
144
|
+
`).run(userId, tenantId, now, now);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
registerBillingRoutes({
|
|
148
|
+
addRoute: (method, path, handler) => routes.set(`${method} ${path}`, handler),
|
|
149
|
+
core,
|
|
150
|
+
context: {
|
|
151
|
+
getRuntimeMode: () => 'cloud'
|
|
152
|
+
},
|
|
153
|
+
ensureAuthenticatedUser: () => true,
|
|
154
|
+
ensureAdminRole: () => opts?.isAdmin !== false,
|
|
155
|
+
requestUserId: () => 'u1',
|
|
156
|
+
resolveErrorStatusCode: (_error, fallback = 500) => fallback,
|
|
157
|
+
auditAdminAction: () => { }
|
|
158
|
+
});
|
|
159
|
+
return routes;
|
|
160
|
+
}
|
|
161
|
+
describe('Billing Webhook Routes', () => {
|
|
162
|
+
const originalEnv = { ...process.env };
|
|
163
|
+
let db;
|
|
164
|
+
let webhookHandler;
|
|
165
|
+
let routeHandlers;
|
|
166
|
+
beforeEach(() => {
|
|
167
|
+
vi.clearAllMocks();
|
|
168
|
+
db = new Database(':memory:');
|
|
169
|
+
setupBillingSchema(db);
|
|
170
|
+
routeHandlers = buildBillingRouteHandlers(db);
|
|
171
|
+
webhookHandler = routeHandlers.get('POST /api/taskforce/billing/webhook');
|
|
172
|
+
process.env.TASKFORCE_BILLING_ENABLED = 'true';
|
|
173
|
+
process.env.TASKFORCE_STRIPE_SECRET_KEY = 'sk_test_123';
|
|
174
|
+
process.env.TASKFORCE_STRIPE_WEBHOOK_SECRET = 'whsec_123';
|
|
175
|
+
});
|
|
176
|
+
afterEach(() => {
|
|
177
|
+
process.env = { ...originalEnv };
|
|
178
|
+
db.close();
|
|
179
|
+
});
|
|
180
|
+
it('returns 400 for invalid webhook signature', async () => {
|
|
181
|
+
mockConstructEvent.mockImplementation(() => {
|
|
182
|
+
throw new Error('invalid signature');
|
|
183
|
+
});
|
|
184
|
+
const req = createMockReq('{"id":"evt_bad"}', {
|
|
185
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
186
|
+
'stripe-signature': 'bad_signature'
|
|
187
|
+
});
|
|
188
|
+
const res = createMockRes();
|
|
189
|
+
await webhookHandler(req, res, {});
|
|
190
|
+
expect(res.statusCode).toBe(400);
|
|
191
|
+
});
|
|
192
|
+
it('returns 200 no-op for duplicate event id', async () => {
|
|
193
|
+
const now = new Date().toISOString();
|
|
194
|
+
db.prepare(`
|
|
195
|
+
INSERT INTO stripe_webhook_events (event_id, tenant_id, event_type, processed_at)
|
|
196
|
+
VALUES (?, 'default', ?, ?)
|
|
197
|
+
`).run('evt_dupe', 'invoice.paid', now);
|
|
198
|
+
mockConstructEvent.mockReturnValue({
|
|
199
|
+
id: 'evt_dupe',
|
|
200
|
+
type: 'invoice.paid',
|
|
201
|
+
data: {
|
|
202
|
+
object: {
|
|
203
|
+
customer: 'cus_1',
|
|
204
|
+
lines: { data: [{ price: { id: 'price_1', recurring: { interval: 'month' } } }] }
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
const req = createMockReq('{"id":"evt_dupe"}', {
|
|
209
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
210
|
+
'stripe-signature': 'sig'
|
|
211
|
+
});
|
|
212
|
+
const res = createMockRes();
|
|
213
|
+
await webhookHandler(req, res, {});
|
|
214
|
+
expect(res.statusCode).toBe(200);
|
|
215
|
+
expect(JSON.parse(res.body)).toEqual({ received: true, duplicate: true });
|
|
216
|
+
});
|
|
217
|
+
it('returns 500 on processing failure so Stripe can retry', async () => {
|
|
218
|
+
mockConstructEvent.mockReturnValue({
|
|
219
|
+
id: 'evt_fail',
|
|
220
|
+
type: 'invoice.paid',
|
|
221
|
+
data: {
|
|
222
|
+
object: {
|
|
223
|
+
customer: 'cus_missing',
|
|
224
|
+
lines: { data: [{ price: { id: 'price_1', recurring: { interval: 'month' } } }] }
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
const req = createMockReq('{"id":"evt_fail"}', {
|
|
229
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
230
|
+
'stripe-signature': 'sig'
|
|
231
|
+
});
|
|
232
|
+
const res = createMockRes();
|
|
233
|
+
await webhookHandler(req, res, {});
|
|
234
|
+
expect(res.statusCode).toBe(500);
|
|
235
|
+
const failures = db.prepare(`SELECT event_id, reason FROM stripe_webhook_failures WHERE event_id = ?`).all('evt_fail');
|
|
236
|
+
expect(failures.length).toBeGreaterThan(0);
|
|
237
|
+
expect(failures[0]?.reason || '').toContain('Unable to resolve user for invoice event.');
|
|
238
|
+
});
|
|
239
|
+
it('preserves existing entitlement on unknown price_id and logs failure', async () => {
|
|
240
|
+
const now = new Date().toISOString();
|
|
241
|
+
db.prepare(`
|
|
242
|
+
INSERT INTO user_billing (user_id, tenant_id, stripe_customer_id, entitlement_state, created_at, updated_at)
|
|
243
|
+
VALUES ('u1', 'default', 'cus_123', 'free', ?, ?)
|
|
244
|
+
`).run(now, now);
|
|
245
|
+
db.prepare(`
|
|
246
|
+
INSERT INTO account_entitlements (
|
|
247
|
+
account_id, tenant_id, plan_version_id, entitlement_state, effective_at, created_at, updated_at
|
|
248
|
+
) VALUES ('u1', 'default', 'starter-v1', 'active', ?, ?, ?)
|
|
249
|
+
`).run(now, now, now);
|
|
250
|
+
mockConstructEvent.mockReturnValue({
|
|
251
|
+
id: 'evt_unknown_price',
|
|
252
|
+
type: 'customer.subscription.updated',
|
|
253
|
+
data: {
|
|
254
|
+
object: {
|
|
255
|
+
id: 'sub_123',
|
|
256
|
+
customer: 'cus_123',
|
|
257
|
+
status: 'active',
|
|
258
|
+
trial_end: null,
|
|
259
|
+
metadata: {},
|
|
260
|
+
items: {
|
|
261
|
+
data: [{
|
|
262
|
+
current_period_end: Math.floor(Date.now() / 1000) + 86400,
|
|
263
|
+
price: { id: 'price_unknown', recurring: { interval: 'month' } }
|
|
264
|
+
}]
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
const req = createMockReq('{"id":"evt_unknown_price"}', {
|
|
270
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
271
|
+
'stripe-signature': 'sig'
|
|
272
|
+
});
|
|
273
|
+
const res = createMockRes();
|
|
274
|
+
await webhookHandler(req, res, {});
|
|
275
|
+
expect(res.statusCode).toBe(200);
|
|
276
|
+
const entitlement = db.prepare(`
|
|
277
|
+
SELECT plan_version_id
|
|
278
|
+
FROM account_entitlements
|
|
279
|
+
WHERE account_id = 'u1' AND tenant_id = 'default'
|
|
280
|
+
`).get();
|
|
281
|
+
expect(entitlement.plan_version_id).toBe('starter-v1');
|
|
282
|
+
const failure = db.prepare(`
|
|
283
|
+
SELECT reason
|
|
284
|
+
FROM stripe_webhook_failures
|
|
285
|
+
WHERE event_id = 'evt_unknown_price'
|
|
286
|
+
ORDER BY created_at DESC
|
|
287
|
+
LIMIT 1
|
|
288
|
+
`).get();
|
|
289
|
+
expect(failure.reason).toContain('Unknown price mapping');
|
|
290
|
+
});
|
|
291
|
+
it('purges expired webhook failures during webhook processing', async () => {
|
|
292
|
+
const past = new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString();
|
|
293
|
+
const now = new Date().toISOString();
|
|
294
|
+
db.prepare(`
|
|
295
|
+
INSERT INTO stripe_webhook_failures (id, tenant_id, event_id, event_type, reason, payload_excerpt, purge_after, created_at)
|
|
296
|
+
VALUES ('whf_old', 'default', 'evt_old', 'invoice.paid', 'old', '{}', ?, ?)
|
|
297
|
+
`).run(past, now);
|
|
298
|
+
db.prepare(`
|
|
299
|
+
INSERT INTO stripe_webhook_events (event_id, tenant_id, event_type, processed_at)
|
|
300
|
+
VALUES ('evt_dup_for_purge', 'default', 'invoice.paid', ?)
|
|
301
|
+
`).run(now);
|
|
302
|
+
mockConstructEvent.mockReturnValue({
|
|
303
|
+
id: 'evt_dup_for_purge',
|
|
304
|
+
type: 'invoice.paid',
|
|
305
|
+
data: { object: { customer: 'cus_1', lines: { data: [] } } }
|
|
306
|
+
});
|
|
307
|
+
const req = createMockReq('{"id":"evt_dup_for_purge"}', {
|
|
308
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
309
|
+
'stripe-signature': 'sig'
|
|
310
|
+
});
|
|
311
|
+
const res = createMockRes();
|
|
312
|
+
await webhookHandler(req, res, {});
|
|
313
|
+
expect(res.statusCode).toBe(200);
|
|
314
|
+
const row = db.prepare(`SELECT id FROM stripe_webhook_failures WHERE id = 'whf_old'`).get();
|
|
315
|
+
expect(row).toBeUndefined();
|
|
316
|
+
});
|
|
317
|
+
it('creates checkout session with billing success/cancel URLs', async () => {
|
|
318
|
+
const now = new Date().toISOString();
|
|
319
|
+
db.prepare(`
|
|
320
|
+
INSERT INTO plan_versions (plan_version_id, tenant_id, plan_id, version_number, is_default, metadata_json, created_at, updated_at)
|
|
321
|
+
VALUES ('team-v1', 'default', 'team', 1, 1, '{}', ?, ?)
|
|
322
|
+
`).run(now, now);
|
|
323
|
+
db.prepare(`
|
|
324
|
+
INSERT INTO billing_price_mappings (tenant_id, plan_version_id, billing_interval, stripe_price_id, active, created_at, updated_at)
|
|
325
|
+
VALUES ('default', 'team-v1', 'month', 'price_team_month', 1, ?, ?)
|
|
326
|
+
`).run(now, now);
|
|
327
|
+
const checkoutHandler = routeHandlers.get('POST /api/taskforce/billing/checkout-session');
|
|
328
|
+
expect(checkoutHandler).toBeTypeOf('function');
|
|
329
|
+
const req = createMockReq(JSON.stringify({
|
|
330
|
+
tier: 'team',
|
|
331
|
+
interval: 'month'
|
|
332
|
+
}), {
|
|
333
|
+
'x-taskforce-runtime-mode': 'cloud',
|
|
334
|
+
host: 'app.taskforcehq.ai'
|
|
335
|
+
});
|
|
336
|
+
const res = createMockRes();
|
|
337
|
+
await checkoutHandler(req, res, {});
|
|
338
|
+
expect(res.statusCode).toBe(200);
|
|
339
|
+
expect(mockCheckoutCreate).toHaveBeenCalledTimes(1);
|
|
340
|
+
const firstCall = mockCheckoutCreate.mock.calls[0];
|
|
341
|
+
const args = (Array.isArray(firstCall) ? firstCall[0] : {});
|
|
342
|
+
expect(String(args.success_url || '')).toContain('/billing/success');
|
|
343
|
+
expect(String(args.cancel_url || '')).toContain('/billing/cancel');
|
|
344
|
+
expect(args.line_items?.[0]?.price).toBe('price_team_month');
|
|
345
|
+
});
|
|
346
|
+
it('lists webhook failure diagnostics for system admin', async () => {
|
|
347
|
+
const now = new Date().toISOString();
|
|
348
|
+
const old = new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString();
|
|
349
|
+
db.prepare(`
|
|
350
|
+
INSERT INTO stripe_webhook_failures (id, tenant_id, event_id, event_type, reason, payload_excerpt, purge_after, created_at)
|
|
351
|
+
VALUES ('whf_keep_1', 'default', 'evt_1', 'invoice.paid', 'diagnostic-1', '{"id":"evt_1"}', ?, ?)
|
|
352
|
+
`).run(new Date(Date.now() + 48 * 60 * 60 * 1000).toISOString(), now);
|
|
353
|
+
db.prepare(`
|
|
354
|
+
INSERT INTO stripe_webhook_failures (id, tenant_id, event_id, event_type, reason, payload_excerpt, purge_after, created_at)
|
|
355
|
+
VALUES ('whf_purge_1', 'default', 'evt_old', 'invoice.paid', 'diagnostic-old', '{"id":"evt_old"}', ?, ?)
|
|
356
|
+
`).run(old, now);
|
|
357
|
+
const route = routeHandlers.get('GET /api/taskforce/admin/billing/webhook-failures');
|
|
358
|
+
expect(route).toBeTypeOf('function');
|
|
359
|
+
const req = createMockReq('', {
|
|
360
|
+
'x-taskforce-runtime-mode': 'cloud'
|
|
361
|
+
});
|
|
362
|
+
req.url = '/api/taskforce/admin/billing/webhook-failures?limit=10';
|
|
363
|
+
const res = createMockRes();
|
|
364
|
+
await route(req, res, {});
|
|
365
|
+
expect(res.statusCode).toBe(200);
|
|
366
|
+
const payload = JSON.parse(res.body);
|
|
367
|
+
expect(payload.purgedExpiredRows).toBeGreaterThanOrEqual(1);
|
|
368
|
+
expect(payload.total).toBeGreaterThanOrEqual(1);
|
|
369
|
+
expect(Array.isArray(payload.rows)).toBe(true);
|
|
370
|
+
expect(payload.rows[0]).toEqual(expect.objectContaining({
|
|
371
|
+
event_id: 'evt_1',
|
|
372
|
+
reason: 'diagnostic-1'
|
|
373
|
+
}));
|
|
374
|
+
});
|
|
375
|
+
it('rejects webhook failure diagnostics for non-admin', async () => {
|
|
376
|
+
const nonAdminHandlers = buildBillingRouteHandlers(db, { isAdmin: false });
|
|
377
|
+
const route = nonAdminHandlers.get('GET /api/taskforce/admin/billing/webhook-failures');
|
|
378
|
+
expect(route).toBeTypeOf('function');
|
|
379
|
+
const req = createMockReq('', {
|
|
380
|
+
'x-taskforce-runtime-mode': 'cloud'
|
|
381
|
+
});
|
|
382
|
+
req.url = '/api/taskforce/admin/billing/webhook-failures';
|
|
383
|
+
const res = createMockRes();
|
|
384
|
+
await route(req, res, {});
|
|
385
|
+
expect(res.statusCode).toBe(403);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taskforce API Routes
|
|
3
|
+
*
|
|
4
|
+
* Extracted from vite.ts plugin to be reusable in both Vite plugin and standalone server.
|
|
5
|
+
* This is a minimal implementation with core routes - additional routes can be added incrementally.
|
|
6
|
+
*/
|
|
7
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
|
+
import { TaskforceCore } from '../core/Taskforce.js';
|
|
9
|
+
import { type TaskforceAuthConfig } from './auth.js';
|
|
10
|
+
import { type ResolvedObjectStorageConfig } from '../storage/objectStorage.js';
|
|
11
|
+
export type RouteHandler = (req: IncomingMessage, res: ServerResponse, params: Record<string, string>) => Promise<void>;
|
|
12
|
+
export interface Route {
|
|
13
|
+
pattern: RegExp;
|
|
14
|
+
keys: string[];
|
|
15
|
+
handler: RouteHandler;
|
|
16
|
+
}
|
|
17
|
+
export declare function parseJsonBody(req: IncomingMessage, maxBytes?: number): Promise<any>;
|
|
18
|
+
/**
|
|
19
|
+
* Create API routes for Taskforce
|
|
20
|
+
*
|
|
21
|
+
* Core routes (29 total):
|
|
22
|
+
*
|
|
23
|
+
* **Task Management (12 routes)**
|
|
24
|
+
* - GET /api/taskforce/config
|
|
25
|
+
* - GET /api/taskforce/tasks
|
|
26
|
+
* - POST /api/taskforce/task
|
|
27
|
+
* - PATCH /api/taskforce/task/:id
|
|
28
|
+
* - DELETE /api/taskforce/task/:id
|
|
29
|
+
* - GET /api/taskforce/archive
|
|
30
|
+
* - POST /api/taskforce/task/:id/complete
|
|
31
|
+
* - POST /api/taskforce/task/:id/cancel
|
|
32
|
+
* - POST /api/taskforce/task/:id/comment
|
|
33
|
+
* - POST /api/taskforce/task/:id/unarchive
|
|
34
|
+
* - POST /api/taskforce/bulk-create
|
|
35
|
+
* - POST /api/taskforce/bulk-archive
|
|
36
|
+
* - POST /api/taskforce/bulk-update-fields
|
|
37
|
+
* - POST /api/taskforce/bulk-update-fields/preview
|
|
38
|
+
*
|
|
39
|
+
* **Configuration Management (10 routes)**
|
|
40
|
+
* - GET /api/taskforce/categories
|
|
41
|
+
* - POST /api/taskforce/categories
|
|
42
|
+
* - GET /api/taskforce/types
|
|
43
|
+
* - POST /api/taskforce/types
|
|
44
|
+
* - GET /api/taskforce/priorities
|
|
45
|
+
* - POST /api/taskforce/priorities
|
|
46
|
+
* - GET /api/taskforce/approaches
|
|
47
|
+
* - POST /api/taskforce/approaches
|
|
48
|
+
* - GET /api/taskforce/taxonomies
|
|
49
|
+
* - POST /api/taskforce/taxonomies
|
|
50
|
+
* - GET /api/taskforce/initiative-templates
|
|
51
|
+
* - POST /api/taskforce/initiative-templates/create
|
|
52
|
+
* - POST /api/taskforce/initiative-templates/clone-checklists
|
|
53
|
+
*
|
|
54
|
+
* **Advanced Features (7 routes)**
|
|
55
|
+
* - POST /api/taskforce/screenshot
|
|
56
|
+
* - GET /api/taskforce/screenshot/:filename
|
|
57
|
+
* - DELETE /api/taskforce/screenshot/:filename
|
|
58
|
+
* - GET /api/taskforce/specialists
|
|
59
|
+
* - GET /api/taskforce/folders
|
|
60
|
+
* - POST /api/taskforce/validate-paths
|
|
61
|
+
* - POST /api/taskforce/export-resources
|
|
62
|
+
* - GET /api/taskforce/health
|
|
63
|
+
*/
|
|
64
|
+
export interface RouteContext {
|
|
65
|
+
authConfig?: TaskforceAuthConfig;
|
|
66
|
+
objectStorage?: ResolvedObjectStorageConfig;
|
|
67
|
+
}
|
|
68
|
+
export declare function createRoutes(core: TaskforceCore, context?: RouteContext): Route[];
|
|
69
|
+
export declare function matchRoute(method: string, pathname: string, routes: Route[]): {
|
|
70
|
+
handler: RouteHandler;
|
|
71
|
+
params: Record<string, string>;
|
|
72
|
+
} | null;
|