@taskforcehq/taskforce 0.3.169 → 0.3.300
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 +52 -21
- package/dist/Taskforce.module.css +3394 -5981
- package/dist/TaskforceCore.CategoryFallback.test.js +5 -2
- package/dist/TaskforceCore.filter-persistence.test.js +402 -0
- package/dist/TaskforceCore.js +388 -71
- package/dist/TaskforceCore.routing.test.js +311 -0
- package/dist/TaskforceCore.test.js +3344 -615
- package/dist/TaskforceWidget.js +3 -2
- package/dist/__tests__/localizationCatalogs.test.js +48 -31
- package/dist/__tests__/workflowSimulation.test.js +2 -2
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +60 -0
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +324 -0
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.js +278 -0
- package/dist/annotatedAttachments/payload.d.ts +2 -0
- package/dist/annotatedAttachments/payload.js +54 -0
- package/dist/annotatedAttachments/payload.test.js +67 -0
- package/dist/annotatedAttachments/service.d.ts +49 -0
- package/dist/annotatedAttachments/service.js +121 -0
- package/dist/annotatedAttachments/types.d.ts +86 -0
- package/dist/cli.js +74 -25
- package/dist/compat/deploymentCompat.d.ts +12 -0
- package/dist/compat/deploymentCompat.js +43 -0
- package/dist/compat/workspaceSyncCompat.d.ts +6 -0
- package/dist/compat/workspaceSyncCompat.js +79 -0
- package/dist/compat/workspaceSyncCompat.test.js +87 -0
- package/dist/components/features/AgentsModule.d.ts +5 -0
- package/dist/components/features/AgentsModule.js +131 -0
- package/dist/components/features/AgentsModule.test.js +102 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +24 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +1942 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +2831 -0
- package/dist/components/features/DocumentGenerateModal.js +8 -16
- package/dist/components/features/DocumentIndex.d.ts +3 -4
- package/dist/components/features/DocumentIndex.js +22 -10
- package/dist/components/features/DocumentViewer.d.ts +6 -2
- package/dist/components/features/DocumentViewer.js +1000 -18
- package/dist/components/features/DocumentWorkspace.d.ts +40 -2
- package/dist/components/features/DocumentWorkspace.js +96 -16
- package/dist/components/features/DocumentWorkspace.test.js +1202 -0
- package/dist/components/features/InitiativesModule.d.ts +22 -0
- package/dist/components/features/InitiativesModule.js +33 -0
- package/dist/components/features/TaskSettings.d.ts +41 -32
- package/dist/components/features/TaskSettings.js +798 -313
- package/dist/components/features/TaskSettings.test.js +1221 -47
- package/dist/components/features/WorkflowsModule.d.ts +27 -0
- package/dist/components/features/WorkflowsModule.js +21 -0
- package/dist/components/features/documentWorkspaceFilters.d.ts +10 -0
- package/dist/components/features/documentWorkspaceFilters.js +11 -0
- package/dist/components/features/settings/CategoryManager.d.ts +2 -0
- package/dist/components/features/settings/CategoryManager.js +15 -8
- package/dist/components/features/settings/PriorityManager.d.ts +18 -0
- package/dist/components/features/settings/PriorityManager.js +51 -0
- package/dist/components/features/settings/TaxonomyEditor.d.ts +2 -1
- package/dist/components/features/settings/TaxonomyEditor.js +41 -18
- package/dist/components/features/settings/TaxonomyLibraryManager.d.ts +26 -0
- package/dist/components/features/settings/TaxonomyLibraryManager.js +301 -0
- package/dist/components/features/settings/TaxonomyLibraryManager.test.js +141 -0
- package/dist/components/features/settings/TaxonomyManager.d.ts +35 -12
- package/dist/components/features/settings/TaxonomyManager.js +59 -27
- package/dist/components/features/settings/TypeManager.d.ts +11 -0
- package/dist/components/features/settings/TypeManager.js +48 -11
- package/dist/components/features/settings/{WorkflowEditorPrototype.d.ts → WorkflowEditor.d.ts} +2 -2
- package/dist/components/features/settings/{WorkflowEditorPrototype.js → WorkflowEditor.js} +3 -3
- package/dist/components/task/TaskActionHeader.d.ts +12 -2
- package/dist/components/task/TaskActionHeader.js +64 -8
- package/dist/components/task/TaskActionHeader.test.js +73 -0
- package/dist/components/task/TaskCard.d.ts +14 -16
- package/dist/components/task/TaskCard.js +144 -174
- package/dist/components/task/TaskCard.test.js +416 -64
- package/dist/components/task/TaskContextUpload.d.ts +6 -5
- package/dist/components/task/TaskContextUpload.js +199 -64
- package/dist/components/task/TaskContextUpload.test.js +331 -14
- package/dist/components/task/TaskForm.d.ts +23 -29
- package/dist/components/task/TaskForm.js +348 -169
- package/dist/components/task/TaskForm.test.js +419 -23
- package/dist/components/task/TaskKanban.d.ts +20 -21
- package/dist/components/task/TaskKanban.js +176 -316
- package/dist/components/task/TaskKanban.planning-drop.test.js +93 -0
- package/dist/components/task/TaskList.d.ts +22 -11
- package/dist/components/task/TaskList.js +98 -12
- package/dist/components/task/TaskList.test.js +206 -7
- package/dist/components/task/TaskReferenceBadge.d.ts +12 -0
- package/dist/components/task/TaskReferenceBadge.js +5 -0
- package/dist/components/task/TaskStatusActions.d.ts +12 -0
- package/dist/components/task/TaskStatusActions.js +18 -0
- package/dist/components/task/TaskStatusActions.test.js +45 -0
- package/dist/components/ui/ImageReferenceBadge.d.ts +12 -0
- package/dist/components/ui/ImageReferenceBadge.js +5 -0
- package/dist/components/ui/LevelSelector.d.ts +2 -1
- package/dist/components/ui/LevelSelector.js +2 -2
- package/dist/components/ui/Markdown.d.ts +1 -2
- package/dist/components/ui/Markdown.js +2 -13
- package/dist/components/ui/Modal.d.ts +3 -2
- package/dist/components/ui/Modal.js +4 -3
- package/dist/components/ui/MultiSelectFilter.d.ts +3 -1
- package/dist/components/ui/MultiSelectFilter.js +2 -2
- package/dist/components/ui/ReferenceBadgeButton.d.ts +13 -0
- package/dist/components/ui/ReferenceBadgeButton.js +6 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +7 -1
- package/dist/components/ui/TaxonomyDropdown.js +58 -23
- package/dist/components/ui/TopNoticeLayer.d.ts +7 -0
- package/dist/components/ui/TopNoticeLayer.js +14 -0
- package/dist/components/ui/TopNoticeLayer.test.js +25 -0
- package/dist/components/views/AppShellHeader.d.ts +13 -0
- package/dist/components/views/AppShellHeader.js +19 -0
- package/dist/components/views/AppShellHeader.test.js +21 -0
- package/dist/components/views/PlanComparisonPage.d.ts +73 -0
- package/dist/components/views/PlanComparisonPage.js +196 -0
- package/dist/components/views/PlanComparisonPage.test.js +251 -0
- package/dist/components/views/PlansPage.d.ts +14 -0
- package/dist/components/views/PlansPage.js +355 -0
- package/dist/components/views/StandaloneLayout.d.ts +2 -2
- package/dist/components/views/StandaloneLayout.js +2212 -1194
- package/dist/components/views/WidgetView.d.ts +2 -2
- package/dist/components/views/WidgetView.js +149 -43
- package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +57 -0
- package/dist/components/views/chrome/WorkspaceChromeSections.js +38 -0
- package/dist/components/views/chrome/WorkspaceChromeSections.test.js +54 -0
- package/dist/components/views/chrome/workspaceChrome.d.ts +31 -0
- package/dist/components/views/chrome/workspaceChrome.js +108 -0
- package/dist/components/views/chrome/workspaceChrome.test.js +52 -0
- package/dist/components/views/panels/DocumentFilterToolbar.d.ts +10 -0
- package/dist/components/views/panels/DocumentFilterToolbar.js +7 -0
- package/dist/components/views/panels/DocumentFilterToolbar.test.js +19 -0
- package/dist/components/views/panels/FilterToolbar.d.ts +66 -0
- package/dist/components/views/panels/FilterToolbar.js +21 -0
- package/dist/components/views/panels/FilterToolbar.test.d.ts +1 -0
- package/dist/components/views/panels/FilterToolbar.test.js +45 -0
- package/dist/components/views/panels/FilterToolbarControls.d.ts +46 -0
- package/dist/components/views/panels/FilterToolbarControls.js +61 -0
- package/dist/components/views/panels/PlanningDrawer.d.ts +115 -0
- package/dist/components/views/panels/PlanningDrawer.js +220 -0
- package/dist/components/views/panels/ScheduleSidebar.d.ts +52 -0
- package/dist/components/views/panels/ScheduleSidebar.js +127 -0
- package/dist/components/views/panels/scheduleUtils.d.ts +14 -0
- package/dist/components/views/panels/scheduleUtils.js +79 -0
- package/dist/components/views/teamManagementAccess.d.ts +6 -0
- package/dist/components/views/teamManagementAccess.js +18 -0
- package/dist/components/views/teamManagementAccess.test.d.ts +1 -0
- package/dist/components/views/teamManagementAccess.test.js +44 -0
- package/dist/config/clientDeployment.d.ts +2 -0
- package/dist/config/clientDeployment.js +13 -0
- package/dist/config/cloudEnvironment.d.ts +15 -0
- package/dist/config/cloudEnvironment.js +60 -0
- package/dist/config/deployment.d.ts +20 -0
- package/dist/config/deployment.js +67 -0
- package/dist/config/deployment.test.d.ts +1 -0
- package/dist/config/deployment.test.js +88 -0
- package/dist/config/envSchema.js +36 -8
- package/dist/config/envSchema.test.js +28 -0
- package/dist/core/AiProfileService.d.ts +66 -0
- package/dist/core/AiProfileService.js +320 -0
- package/dist/core/AiProfileService.test.d.ts +1 -0
- package/dist/core/AiProfileService.test.js +164 -0
- package/dist/core/AiProfiles.test.d.ts +1 -0
- package/dist/core/AiProfiles.test.js +449 -0
- package/dist/core/AttachmentLinkService.d.ts +15 -0
- package/dist/core/AttachmentLinkService.js +157 -0
- package/dist/core/AuthTokenService.d.ts +44 -0
- package/dist/core/AuthTokenService.js +207 -0
- package/dist/core/CreatedBy.test.js +134 -6
- package/dist/core/DeletedTaskLifecycleService.d.ts +33 -0
- package/dist/core/DeletedTaskLifecycleService.js +158 -0
- package/dist/core/DeletedTaskTrash.test.d.ts +1 -0
- package/dist/core/DeletedTaskTrash.test.js +104 -0
- package/dist/core/EntitlementsPolicy.test.js +78 -5
- package/dist/core/GlobalSettingsService.d.ts +16 -0
- package/dist/core/GlobalSettingsService.js +370 -0
- package/dist/core/JsonBackupRuntime.test.d.ts +1 -0
- package/dist/core/JsonBackupRuntime.test.js +155 -0
- package/dist/core/McpTokenService.d.ts +118 -0
- package/dist/core/McpTokenService.js +921 -0
- package/dist/core/PlanEntitlementService.d.ts +201 -0
- package/dist/core/PlanEntitlementService.js +1442 -0
- package/dist/core/PlanVersionPolicy.test.d.ts +1 -0
- package/dist/core/PlanVersionPolicy.test.js +178 -0
- package/dist/core/PlanningEntities.test.d.ts +1 -0
- package/dist/core/PlanningEntities.test.js +95 -0
- package/dist/core/ScheduleFields.test.js +15 -19
- package/dist/core/SignupMonetizationSettings.test.d.ts +1 -0
- package/dist/core/SignupMonetizationSettings.test.js +159 -0
- package/dist/core/Stats.test.d.ts +1 -0
- package/dist/core/Stats.test.js +36 -0
- package/dist/core/SyncReconciliationService.d.ts +93 -0
- package/dist/core/SyncReconciliationService.js +406 -0
- package/dist/core/SystemAdmin.test.js +578 -13
- package/dist/core/TaskActivityService.d.ts +21 -0
- package/dist/core/TaskActivityService.js +130 -0
- package/dist/core/TaskAttachmentsCanonical.test.d.ts +1 -0
- package/dist/core/TaskAttachmentsCanonical.test.js +306 -0
- package/dist/core/TaskAuditTimeline.test.d.ts +1 -0
- package/dist/core/TaskAuditTimeline.test.js +132 -0
- package/dist/core/TaskTaxonomyValidation.test.js +338 -15
- package/dist/core/Taskforce.d.ts +930 -183
- package/dist/core/Taskforce.ids.test.js +252 -0
- package/dist/core/Taskforce.js +3848 -2532
- package/dist/core/Taskforce.mcpAuth.test.d.ts +1 -0
- package/dist/core/Taskforce.mcpAuth.test.js +343 -0
- package/dist/core/Taskforce.realtimeMutation.test.js +57 -2
- package/dist/core/TaxonomySettingsService.d.ts +18 -0
- package/dist/core/TaxonomySettingsService.js +162 -0
- package/dist/core/WorkspaceDelete.test.js +32 -13
- package/dist/core/WorkspaceLifecycleService.d.ts +11 -0
- package/dist/core/WorkspaceLifecycleService.js +88 -0
- package/dist/core/WorkspacePermissions.test.js +95 -0
- package/dist/core/WorkspacePlanMode.test.js +114 -1
- package/dist/core/WorkspacePreferenceService.d.ts +41 -0
- package/dist/core/WorkspacePreferenceService.js +246 -0
- package/dist/core/WorkspaceSyncSettings.test.d.ts +1 -0
- package/dist/core/WorkspaceSyncSettings.test.js +65 -0
- package/dist/core/__tests__/TaskAttachmentsCanonical.test.d.ts +1 -0
- package/dist/core/__tests__/TaskAttachmentsCanonical.test.js +212 -0
- package/dist/core/shared.d.ts +36 -0
- package/dist/core/shared.js +128 -0
- package/dist/core/types.d.ts +614 -0
- package/dist/core/types.js +27 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +56 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +230 -0
- package/dist/documentReviews/DocumentReviewSessionStore.d.ts +52 -0
- package/dist/documentReviews/DocumentReviewSessionStore.js +193 -0
- package/dist/documentReviews/DocumentReviewSessionStore.test.d.ts +1 -0
- package/dist/documentReviews/DocumentReviewSessionStore.test.js +127 -0
- package/dist/documentReviews/service.d.ts +68 -0
- package/dist/documentReviews/service.js +210 -0
- package/dist/documentReviews/types.d.ts +58 -0
- package/dist/documentReviews/types.js +1 -0
- package/dist/hooks/auth/useAuthGuardPolicy.d.ts +2 -0
- package/dist/hooks/auth/useAuthGuardPolicy.js +1 -0
- package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +15 -0
- package/dist/hooks/tasks/useCurrentTaskRelations.js +37 -0
- package/dist/hooks/tasks/useTaskActions.d.ts +3 -0
- package/dist/hooks/tasks/useTaskActions.js +2 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +65 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.js +235 -0
- package/dist/hooks/tasks/useTaskFilters.d.ts +2 -0
- package/dist/hooks/tasks/useTaskFilters.js +2 -0
- package/dist/hooks/tasks/useTaskFormActions.d.ts +58 -0
- package/dist/hooks/tasks/useTaskFormActions.js +365 -0
- package/dist/hooks/tasks/useTaskRelationships.d.ts +16 -0
- package/dist/hooks/tasks/useTaskRelationships.js +64 -0
- package/dist/hooks/ui/useResourceExport.d.ts +19 -0
- package/dist/hooks/ui/useResourceExport.js +84 -0
- package/dist/hooks/ui/useSettingsModel.d.ts +203 -0
- package/dist/hooks/ui/useSettingsModel.js +125 -0
- package/dist/hooks/ui/useSettingsPersistence.d.ts +36 -0
- package/dist/hooks/ui/useSettingsPersistence.js +254 -0
- package/dist/hooks/ui/useSettingsTaxonomyManagement.d.ts +119 -0
- package/dist/hooks/ui/useSettingsTaxonomyManagement.js +536 -0
- package/dist/hooks/ui/useUiNotice.d.ts +1 -0
- package/dist/hooks/ui/useUiNotice.js +1 -0
- package/dist/hooks/ui/useWorkflowTemplates.d.ts +37 -0
- package/dist/hooks/ui/useWorkflowTemplates.js +111 -0
- package/dist/hooks/ui/useZenMode.d.ts +5 -0
- package/dist/hooks/ui/useZenMode.js +32 -0
- package/dist/hooks/useFilterSort.d.ts +60 -0
- package/dist/hooks/useFilterSort.js +362 -0
- package/dist/hooks/useFilterSort.test.d.ts +1 -0
- package/dist/hooks/useFilterSort.test.js +333 -0
- package/dist/hooks/useRealtimeSync.d.ts +1 -0
- package/dist/hooks/useRealtimeSync.js +24 -9
- package/dist/hooks/useRealtimeSync.test.js +28 -1
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.d.ts +1 -0
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +34 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +65 -103
- package/dist/hooks/useSyncOrchestrator.js +1538 -670
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +700 -174
- package/dist/hooks/useTaskData.d.ts +35 -0
- package/dist/hooks/useTaskData.js +239 -0
- package/dist/hooks/useTaskData.test.d.ts +1 -0
- package/dist/hooks/useTaskData.test.js +119 -0
- package/dist/hooks/useTaskMutations.d.ts +46 -0
- package/dist/hooks/useTaskMutations.js +472 -0
- package/dist/hooks/useTaskMutations.test.d.ts +1 -0
- package/dist/hooks/useTaskMutations.test.js +80 -0
- package/dist/hooks/useTaskforce.contract.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.contract.test.js +7 -0
- package/dist/hooks/useTaskforce.d.ts +260 -295
- package/dist/hooks/useTaskforce.js +1954 -2623
- package/dist/hooks/useTaskforce.priority-filters.test.js +6 -11
- package/dist/hooks/useTaskforce.sync-behavior.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +1120 -0
- package/dist/hooks/useUiNotice.d.ts +16 -0
- package/dist/hooks/useUiNotice.js +49 -0
- package/dist/hooks/useWorkspaceSyncController.d.ts +23 -46
- package/dist/hooks/useWorkspaceSyncController.js +280 -461
- package/dist/hooks/useWorkspaceSyncController.test.js +106 -199
- package/dist/hooks/workspace/useTaskforceApiRouting.d.ts +8 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.js +91 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.test.d.ts +1 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.test.js +60 -0
- package/dist/hooks/workspace/useWorkspaceSyncController.d.ts +1 -0
- package/dist/hooks/workspace/useWorkspaceSyncController.js +1 -0
- package/dist/hooks/workspace/workspaceLocalState.d.ts +30 -0
- package/dist/hooks/workspace/workspaceLocalState.js +101 -0
- package/dist/localization/locales/en-US.d.ts +1 -8
- package/dist/localization/locales/en-US.js +4 -11
- package/dist/localization/locales/es-419.js +2 -9
- package/dist/localization/locales/pt-BR.js +2 -9
- package/dist/localization/localizationCatalogs.test.d.ts +1 -0
- package/dist/localization/localizationCatalogs.test.js +37 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +9 -15
- package/dist/mcp/clientIntegrations.d.ts +33 -0
- package/dist/mcp/clientIntegrations.js +199 -0
- package/dist/mcp/clientIntegrations.test.d.ts +1 -0
- package/dist/mcp/clientIntegrations.test.js +110 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/optionResolution.test.js +6 -2
- package/dist/mcp/runtime.d.ts +120 -0
- package/dist/mcp/runtime.js +5668 -0
- package/dist/mcp/runtime.test.d.ts +1 -0
- package/dist/mcp/runtime.test.js +3293 -0
- package/dist/mcp/server.js +2 -1793
- package/dist/mcp/structuredCommentValidation.test.d.ts +1 -0
- package/dist/{__tests__ → mcp}/structuredCommentValidation.test.js +1 -1
- package/dist/mcp/structuredDocValidation.js +1 -2
- package/dist/mcp/structuredDocValidation.test.d.ts +1 -0
- package/dist/{__tests__ → mcp}/structuredDocValidation.test.js +9 -4
- package/dist/mcp/toolRegistry.d.ts +570 -0
- package/dist/mcp/toolRegistry.js +90 -0
- package/dist/mcp/toolRegistry.test.d.ts +1 -0
- package/dist/mcp/toolRegistry.test.js +30 -0
- package/dist/migrations/billingSchemaParity.test.js +111 -0
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +681 -39
- package/dist/migrations/taskSchemaMigrations.test.d.ts +1 -0
- package/dist/migrations/taskSchemaMigrations.test.js +210 -0
- package/dist/plugins/vite.js +13 -7
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/archive/phoenix/apple-touch-icon.png +0 -0
- package/dist/public/archive/phoenix/favicon.ico +0 -0
- package/dist/public/archive/phoenix/site.webmanifest +1 -0
- package/dist/public/favicon-96x96.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/favicon.svg +17 -0
- package/dist/public/site.webmanifest +21 -1
- package/dist/public/web-app-manifest-192x192.png +0 -0
- package/dist/public/web-app-manifest-512x512.png +0 -0
- package/dist/releaseVersion.test.d.ts +1 -0
- package/dist/{__tests__/releaseVersion.test.js → releaseVersion.test.js} +1 -1
- package/dist/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
- package/dist/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
- package/dist/resources/templates/workflows/collaborate.yaml +11 -5
- package/dist/resources/templates/workflows/do.yaml +8 -2
- package/dist/resources/templates/workflows/evaluate.yaml +13 -7
- package/dist/resources/templates/workflows/execute.yaml +40 -23
- package/dist/resources/templates/workflows/plan.yaml +15 -8
- package/dist/resources/templates/workflows/review.yaml +14 -8
- package/dist/runtime/appGateDefinitions.d.ts +32 -0
- package/dist/runtime/appGateDefinitions.js +32 -0
- package/dist/runtime/appGates.d.ts +29 -0
- package/dist/runtime/appGates.js +53 -0
- package/dist/runtime/appGates.test.d.ts +1 -0
- package/dist/runtime/appGates.test.js +42 -0
- package/dist/runtime/migrationFlags.d.ts +1 -0
- package/dist/runtime/migrationFlags.js +1 -0
- package/dist/server/annotatedAttachmentsRoutes.test.d.ts +1 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +473 -0
- package/dist/server/auth.js +14 -2
- package/dist/server/auth.test.js +21 -1
- package/dist/server/cors.js +11 -5
- package/dist/server/cors.test.js +6 -0
- package/dist/server/documentReviewRoutes.test.d.ts +1 -0
- package/dist/server/documentReviewRoutes.test.js +157 -0
- package/dist/server/index.cookieProxy.test.js +46 -1
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.js +168 -41
- package/dist/server/index.rateLimit.test.js +6 -0
- package/dist/server/index.test.js +133 -2
- package/dist/server/mockStripe.d.ts +72 -0
- package/dist/server/mockStripe.js +357 -0
- package/dist/server/realtimeSyncWs.js +4 -0
- package/dist/server/routes/admin.d.ts +114 -0
- package/dist/server/routes/admin.js +2226 -0
- package/dist/server/routes/annotatedAttachments.d.ts +24 -0
- package/dist/server/routes/annotatedAttachments.js +235 -0
- package/dist/server/routes/auth.d.ts +61 -0
- package/dist/server/routes/auth.js +1296 -0
- package/dist/server/{routes.billing.d.ts → routes/billing.d.ts} +3 -2
- package/dist/server/routes/billing.js +2001 -0
- package/dist/server/routes/billing.test.d.ts +1 -0
- package/dist/server/routes/billing.test.js +1631 -0
- package/dist/server/routes/documentReviews.d.ts +11 -0
- package/dist/server/routes/documentReviews.js +191 -0
- package/dist/server/routes/documents.d.ts +118 -0
- package/dist/server/routes/documents.js +1113 -0
- package/dist/server/routes/resources.d.ts +25 -0
- package/dist/server/routes/resources.js +225 -0
- package/dist/server/routes/shared.d.ts +35 -0
- package/dist/server/routes/shared.js +305 -0
- package/dist/server/routes/shared.test.d.ts +1 -0
- package/dist/server/routes/shared.test.js +32 -0
- package/dist/server/{routes.sync.d.ts → routes/sync.d.ts} +5 -5
- package/dist/server/routes/sync.integration.test.d.ts +1 -0
- package/dist/server/routes/sync.integration.test.js +2003 -0
- package/dist/server/routes/sync.js +3143 -0
- package/dist/server/routes/tasks.d.ts +72 -0
- package/dist/server/routes/tasks.js +1252 -0
- package/dist/server/routes/workspaces.d.ts +32 -0
- package/dist/server/routes/workspaces.js +307 -0
- package/dist/server/routes.d.ts +8 -9
- package/dist/server/routes.js +968 -4092
- package/dist/server/routes.test.js +9043 -2415
- package/dist/server/runtimeMode.d.ts +1 -1
- package/dist/server/runtimeMode.js +3 -18
- package/dist/server/runtimeMode.test.js +3 -3
- package/dist/server/securityHeaders.d.ts +1 -1
- package/dist/server/securityHeaders.js +65 -6
- package/dist/server/securityHeaders.test.js +40 -2
- package/dist/services/templateEngine.test.d.ts +1 -0
- package/dist/{__tests__ → services}/templateEngine.test.js +1 -1
- package/dist/services/templates.test.d.ts +1 -0
- package/dist/{__tests__ → services}/templates.test.js +1 -1
- package/dist/services/workflowDocumentFixtures.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowDocumentFixtures.test.js +4 -4
- package/dist/services/workflowExportMatrix.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowExportMatrix.test.js +1 -1
- package/dist/services/workflowExportSnapshots.test.d.ts +1 -0
- package/dist/services/workflowGeneration.test.d.ts +1 -0
- package/dist/services/workflowSimulation.test.d.ts +1 -0
- package/dist/services/workflowSimulation.test.js +113 -0
- package/dist/services/workflowV2Policy.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowV2Policy.test.js +2 -2
- package/dist/shared/aiProfileSurfaceType.d.ts +9 -0
- package/dist/shared/aiProfileSurfaceType.js +49 -0
- package/dist/shared/customTaxonomyLibrary.d.ts +11 -0
- package/dist/shared/customTaxonomyLibrary.js +276 -0
- package/dist/shared/customTaxonomyLibrary.test.d.ts +1 -0
- package/dist/shared/customTaxonomyLibrary.test.js +20 -0
- package/dist/shared/taxonomyCatalog.d.ts +19 -0
- package/dist/shared/taxonomyCatalog.js +36 -0
- package/dist/shared/taxonomyDefaults.d.ts +29 -0
- package/dist/shared/taxonomyDefaults.js +26 -0
- package/dist/shared/taxonomyLibrary.d.ts +15 -0
- package/dist/shared/taxonomyLibrary.js +98 -0
- package/dist/shared/taxonomyLibrary.test.d.ts +1 -0
- package/dist/shared/taxonomyLibrary.test.js +26 -0
- package/dist/shared/taxonomyState.d.ts +36 -0
- package/dist/shared/taxonomyState.js +73 -0
- package/dist/shared/taxonomyState.test.d.ts +1 -0
- package/dist/shared/taxonomyState.test.js +71 -0
- package/dist/shared/workflowDefaults.d.ts +9 -0
- package/dist/shared/workflowDefaults.js +11 -0
- package/dist/storage/documentIntegrity.d.ts +2 -0
- package/dist/storage/documentIntegrity.js +34 -17
- package/dist/storage/documentPurge.d.ts +2 -1
- package/dist/storage/documentPurge.js +35 -8
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/objectStorage.d.ts +1 -1
- package/dist/storage/objectStorageClient.d.ts +6 -4
- package/dist/storage/objectStorageClient.js +77 -29
- package/dist/storage/objectStorageClient.test.d.ts +1 -0
- package/dist/storage/objectStorageClient.test.js +57 -0
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.d.ts +1 -0
- package/dist/storage/objectStorageConfig.test.js +38 -0
- package/dist/storage/postgresAdapter.d.ts +5 -0
- package/dist/storage/postgresAdapter.js +2 -2
- package/dist/storage/postgresAdapter.test.d.ts +1 -0
- package/dist/storage/postgresAdapter.test.js +29 -0
- package/dist/storage/taskAssetStore.d.ts +7 -4
- package/dist/storage/taskAssetStore.js +65 -60
- package/dist/storage/workspaceAssetStore.d.ts +122 -0
- package/dist/storage/workspaceAssetStore.js +496 -0
- package/dist/storage/workspaceAssetStore.test.d.ts +1 -0
- package/dist/storage/workspaceAssetStore.test.js +501 -0
- package/dist/sync/cloudSyncApi.d.ts +33 -2
- package/dist/sync/cloudSyncApi.js +37 -15
- package/dist/sync/cloudSyncApi.test.js +60 -3
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.js +3 -0
- package/dist/sync/syncService.d.ts +25 -0
- package/dist/sync/syncService.js +184 -16
- package/dist/sync/syncService.test.js +289 -25
- package/dist/sync/workspaceRepair.d.ts +114 -0
- package/dist/sync/workspaceRepair.js +566 -0
- package/dist/sync/workspaceSyncModel.d.ts +230 -2
- package/dist/sync/workspaceSyncModel.js +456 -17
- package/dist/sync/workspaceSyncModel.test.js +642 -0
- package/dist/sync/workspaceSyncState.d.ts +12 -0
- package/dist/sync/workspaceSyncState.js +12 -0
- package/dist/sync/workspaceSyncSurface.d.ts +33 -0
- package/dist/sync/workspaceSyncSurface.js +74 -0
- package/dist/types.d.ts +143 -18
- package/dist/types.js +9 -24
- package/dist/ui/assets/AgentsModule-TVmCgizS.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CAyhnPeR.js +3 -0
- package/dist/ui/assets/DocumentWorkspace-BOCw5e4D.js +250 -0
- package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +1 -0
- package/dist/ui/assets/InitiativesModule-CN0r02Oi.js +1 -0
- package/dist/ui/assets/PlansPage-BlVC_lRq.css +1 -0
- package/dist/ui/assets/PlansPage-FcQSNLZd.js +1 -0
- package/dist/ui/assets/TaskSettings-BwB9NtmJ.css +1 -0
- package/dist/ui/assets/TaskSettings-Cw5zYD1L.js +8 -0
- package/dist/ui/assets/WorkflowsModule-CY9R2zPB.js +5 -0
- package/dist/ui/assets/index-Bzqy5QGm.js +6 -0
- package/dist/ui/assets/index-DxRiI3tY.css +1 -0
- package/dist/ui/assets/vendor-dnd-DRzYolkg.js +5 -0
- package/dist/ui/assets/{vendor-icons-ZFG3SGwo.js → vendor-icons-QZyhEwgT.js} +1 -1
- package/dist/ui/assets/{vendor-markdown-CKYkQHfj.js → vendor-markdown-BUxTU7dS.js} +1 -1
- package/dist/ui/assets/vendor-react-CKJs5o3c.js +61 -0
- package/dist/ui/assets/vendor-router-BbWMxlnO.js +3 -0
- package/dist/ui/branding/logos/logo.png +0 -0
- package/dist/ui/branding/logos/logo_dark.svg +27 -0
- package/dist/ui/branding/logos/logo_favicon.svg +35 -0
- package/dist/ui/branding/logos/logo_light.svg +27 -0
- package/dist/ui/favicon/apple-touch-icon.png +0 -0
- package/dist/ui/favicon/archive/phoenix/apple-touch-icon.png +0 -0
- package/dist/ui/favicon/archive/phoenix/favicon.ico +0 -0
- package/dist/ui/favicon/archive/phoenix/site.webmanifest +1 -0
- package/dist/ui/favicon/favicon-96x96.png +0 -0
- package/dist/ui/favicon/favicon.ico +0 -0
- package/dist/ui/favicon/favicon.svg +17 -0
- package/dist/ui/favicon/site.webmanifest +21 -1
- package/dist/ui/favicon/web-app-manifest-192x192.png +0 -0
- package/dist/ui/favicon/web-app-manifest-512x512.png +0 -0
- package/dist/ui/index.html +10 -7
- package/dist/ui/product/screen_01.png +0 -0
- package/dist/ui/product/screen_02.png +0 -0
- package/dist/ui/product/screen_03.png +0 -0
- package/dist/utils/annotatedAttachments.d.ts +20 -0
- package/dist/utils/annotatedAttachments.js +74 -0
- package/dist/utils/annotatedAttachments.test.d.ts +1 -0
- package/dist/utils/annotatedAttachments.test.js +108 -0
- package/dist/utils/assignees.d.ts +26 -0
- package/dist/utils/assignees.js +132 -0
- package/dist/utils/canonicalAssetKind.d.ts +16 -0
- package/dist/utils/canonicalAssetKind.js +39 -0
- package/dist/utils/canonicalAssetKind.test.d.ts +1 -0
- package/dist/utils/canonicalAssetKind.test.js +24 -0
- package/dist/utils/coalescedRefresh.d.ts +5 -0
- package/dist/utils/coalescedRefresh.js +16 -0
- package/dist/utils/coalescedRefresh.test.d.ts +1 -0
- package/dist/utils/coalescedRefresh.test.js +30 -0
- package/dist/utils/constants.d.ts +16 -3
- package/dist/utils/constants.icons.test.js +2 -1
- package/dist/utils/constants.js +70 -13
- package/dist/utils/contextAssetEvents.d.ts +7 -0
- package/dist/utils/contextAssetEvents.js +6 -0
- package/dist/utils/contextFiles.d.ts +14 -3
- package/dist/utils/contextFiles.js +40 -8
- package/dist/utils/documentManagerApi.d.ts +6 -0
- package/dist/utils/documentManagerApi.js +19 -0
- package/dist/utils/documentNames.d.ts +24 -0
- package/dist/utils/documentNames.js +91 -0
- package/dist/utils/documentReferences.d.ts +9 -0
- package/dist/utils/documentReferences.js +11 -0
- package/dist/utils/entityReferences.d.ts +9 -0
- package/dist/utils/entityReferences.js +32 -0
- package/dist/utils/imageReferences.d.ts +9 -0
- package/dist/utils/imageReferences.js +11 -0
- package/dist/utils/planParser.d.ts +2 -2
- package/dist/utils/planParser.js +11 -11
- package/dist/utils/planParser.test.d.ts +1 -0
- package/dist/{__tests__ → utils}/planParser.test.js +22 -22
- package/dist/utils/planningReferences.d.ts +17 -0
- package/dist/utils/planningReferences.js +30 -0
- package/dist/utils/planningReferences.test.d.ts +1 -0
- package/dist/utils/planningReferences.test.js +17 -0
- package/dist/utils/taskActivity.d.ts +9 -0
- package/dist/utils/taskActivity.js +147 -0
- package/dist/utils/taskActivity.test.d.ts +1 -0
- package/dist/utils/taskActivity.test.js +34 -0
- package/dist/utils/taskDraftDefaults.d.ts +21 -0
- package/dist/utils/taskDraftDefaults.js +40 -0
- package/dist/utils/taskDraftDefaults.test.d.ts +1 -0
- package/dist/utils/taskDraftDefaults.test.js +34 -0
- package/dist/utils/taskNormalization.d.ts +25 -0
- package/dist/utils/taskNormalization.js +161 -0
- package/dist/utils/taskNormalization.test.d.ts +1 -0
- package/dist/utils/taskNormalization.test.js +158 -0
- package/dist/utils/taskReferences.d.ts +5 -0
- package/dist/utils/taskReferences.js +11 -0
- package/dist/utils/taskforceApiClient.d.ts +2 -0
- package/dist/utils/taskforceApiClient.js +101 -3
- package/dist/utils/taskforceApiClient.test.d.ts +1 -0
- package/dist/utils/taskforceApiClient.test.js +44 -0
- package/dist/utils/taxonomyFilterOptions.d.ts +2 -0
- package/dist/utils/taxonomyFilterOptions.js +17 -0
- package/dist/utils/taxonomyFormDefaults.d.ts +3 -0
- package/dist/utils/taxonomyFormDefaults.js +28 -0
- package/dist/utils/taxonomyFormDefaults.test.d.ts +1 -0
- package/dist/utils/taxonomyFormDefaults.test.js +63 -0
- package/dist/utils/taxonomyLifecycle.d.ts +3 -0
- package/dist/utils/taxonomyLifecycle.js +17 -0
- package/dist/utils/taxonomySorting.d.ts +7 -0
- package/dist/utils/taxonomySorting.js +74 -0
- package/dist/utils/theme.d.ts +15 -0
- package/dist/utils/theme.js +23 -0
- package/dist/utils/uiNotice.d.ts +7 -0
- package/dist/utils/uiNotice.js +6 -0
- package/dist/utils/uiNotice.test.d.ts +1 -0
- package/dist/utils/uiNotice.test.js +18 -0
- package/dist/utils/workspaceIdentity.d.ts +14 -0
- package/dist/utils/workspaceIdentity.js +21 -0
- package/dist/utils/workspaceIdentity.test.js +30 -1
- package/dist/utils/workspaceSyncPresentation.d.ts +20 -0
- package/dist/utils/workspaceSyncPresentation.js +21 -0
- package/dist/utils/workspaceSyncPresentation.test.d.ts +1 -0
- package/dist/utils/workspaceSyncPresentation.test.js +36 -0
- package/package.json +28 -23
- package/scripts/bootstrap-playwright-auth.mjs +155 -0
- package/scripts/check-compat-boundaries.mjs +41 -0
- package/scripts/check-env.ts +9 -2
- package/scripts/debug-login.mjs +32 -0
- package/scripts/migrate-planning-model.ts +233 -0
- package/scripts/migrate-task-data-assets.mjs +408 -0
- package/scripts/playwright-auth.sh +11 -0
- package/scripts/run-dev-proxy.sh +2 -0
- package/scripts/update-homebrew-formula.sh +20 -3
- package/scripts/with-esbuild.sh +11 -0
- package/src/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
- package/src/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
- package/src/resources/templates/workflows/collaborate.yaml +11 -5
- package/src/resources/templates/workflows/do.yaml +8 -2
- package/src/resources/templates/workflows/evaluate.yaml +13 -7
- package/src/resources/templates/workflows/execute.yaml +40 -23
- package/src/resources/templates/workflows/plan.yaml +15 -8
- package/src/resources/templates/workflows/review.yaml +14 -8
- package/dist/TaskforceScreenshot.d.ts +0 -11
- package/dist/TaskforceScreenshot.js +0 -113
- package/dist/compat/priorityCompat.d.ts +0 -2
- package/dist/compat/priorityCompat.js +0 -24
- package/dist/components/features/settings/TaxonomyManager 2.d.ts +0 -52
- package/dist/components/features/settings/TaxonomyManager 2.js +0 -75
- package/dist/components/task/TaskKanban 2.d.ts +0 -76
- package/dist/components/task/TaskKanban 2.js +0 -1004
- package/dist/components/task/TaskScreenshotSection.d.ts +0 -15
- package/dist/components/task/TaskScreenshotSection.js +0 -22
- package/dist/components/views/StandaloneLayout 2.d.ts +0 -8
- package/dist/components/views/StandaloneLayout 2.js +0 -1660
- package/dist/core/InitiativeTemplates.test.js +0 -50
- package/dist/core/ParentLifecycle.test.js +0 -98
- package/dist/migrations/clientMigrations.d.ts +0 -9
- package/dist/migrations/clientMigrations.js +0 -74
- package/dist/migrations/flags.d.ts +0 -6
- package/dist/migrations/flags.js +0 -8
- package/dist/migrations/taskMigrations.d.ts +0 -71
- package/dist/migrations/taskMigrations.js +0 -236
- package/dist/migrations/taskMigrations.test.js +0 -34
- package/dist/server/routes.billing.js +0 -991
- package/dist/server/routes.billing.test.js +0 -387
- package/dist/server/routes.sync.integration.test.js +0 -470
- package/dist/server/routes.sync.js +0 -1141
- package/dist/soak/syncSoakHarness.d.ts +0 -6
- package/dist/soak/syncSoakHarness.js +0 -10
- package/dist/ui/assets/index-0W5vyCpn.css +0 -1
- package/dist/ui/assets/index-MCZuNNfn.js +0 -23
- package/dist/ui/assets/logo_white_01-0Vx-iIIv.png +0 -0
- package/dist/ui/assets/vendor-dnd-BI1K77C1.js +0 -5
- package/dist/ui/assets/vendor-react-DdIDsh7f.js +0 -9
- package/dist/ui/assets/vendor-router-BtiNU7Dl.js +0 -3
- package/dist/utils/taskHierarchy.d.ts +0 -4
- package/dist/utils/taskHierarchy.js +0 -69
- package/dist/utils/taskHierarchy.test.js +0 -38
- package/dist/utils/taskParenting.d.ts +0 -3
- package/dist/utils/taskParenting.js +0 -24
- package/dist/utils/taskParenting.test.js +0 -21
- package/dist/utils/taskRelations.d.ts +0 -6
- package/dist/utils/taskRelations.js +0 -24
- package/dist/utils/taskRelations.test.js +0 -34
- package/scripts/check-compat-boundaries.js +0 -48
- /package/dist/{__tests__/planParser.test.d.ts → TaskforceCore.filter-persistence.test.d.ts} +0 -0
- /package/dist/{__tests__/releaseVersion.test.d.ts → TaskforceCore.routing.test.d.ts} +0 -0
- /package/dist/{__tests__/structuredCommentValidation.test.d.ts → annotatedAttachments/AnnotatedAttachmentSessionStore.test.d.ts} +0 -0
- /package/dist/{__tests__/structuredDocValidation.test.d.ts → annotatedAttachments/payload.test.d.ts} +0 -0
- /package/dist/{__tests__/templateEngine.test.d.ts → annotatedAttachments/types.js} +0 -0
- /package/dist/{__tests__/templates.test.d.ts → compat/workspaceSyncCompat.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowDocumentFixtures.test.d.ts → components/features/AgentsModule.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowExportMatrix.test.d.ts → components/features/AnnotatedAttachmentWorkspace.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowExportSnapshots.test.d.ts → components/features/DocumentWorkspace.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowGeneration.test.d.ts → components/features/settings/TaxonomyLibraryManager.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowV2Policy.test.d.ts → components/task/TaskActionHeader.test.d.ts} +0 -0
- /package/dist/{core/InitiativeTemplates.test.d.ts → components/task/TaskKanban.planning-drop.test.d.ts} +0 -0
- /package/dist/{core/ParentLifecycle.test.d.ts → components/task/TaskStatusActions.test.d.ts} +0 -0
- /package/dist/{migrations/taskMigrations.test.d.ts → components/ui/TopNoticeLayer.test.d.ts} +0 -0
- /package/dist/{server/routes.billing.test.d.ts → components/views/AppShellHeader.test.d.ts} +0 -0
- /package/dist/{server/routes.sync.integration.test.d.ts → components/views/PlanComparisonPage.test.d.ts} +0 -0
- /package/dist/{utils/taskHierarchy.test.d.ts → components/views/chrome/WorkspaceChromeSections.test.d.ts} +0 -0
- /package/dist/{utils/taskParenting.test.d.ts → components/views/chrome/workspaceChrome.test.d.ts} +0 -0
- /package/dist/{utils/taskRelations.test.d.ts → components/views/panels/DocumentFilterToolbar.test.d.ts} +0 -0
- /package/dist/public/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
- /package/dist/public/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
- /package/dist/public/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
- /package/dist/public/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
- /package/dist/public/{favicon.png → archive/phoenix/favicon.png} +0 -0
- /package/dist/{__tests__ → services}/workflowExportSnapshots.test.js +0 -0
- /package/dist/{__tests__ → services}/workflowGeneration.test.js +0 -0
- /package/dist/ui/favicon/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
- /package/dist/ui/favicon/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
- /package/dist/ui/favicon/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
- /package/dist/ui/favicon/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
- /package/dist/ui/favicon/{favicon.png → archive/phoenix/favicon.png} +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function basename(value) {
|
|
2
|
+
const normalized = String(value || '').trim().replace(/\\/g, '/');
|
|
3
|
+
if (!normalized)
|
|
4
|
+
return '';
|
|
5
|
+
const segments = normalized.split('/').filter(Boolean);
|
|
6
|
+
return segments[segments.length - 1] || '';
|
|
7
|
+
}
|
|
8
|
+
function splitExtension(filename) {
|
|
9
|
+
const trimmed = String(filename || '').trim();
|
|
10
|
+
const dotIndex = trimmed.lastIndexOf('.');
|
|
11
|
+
if (dotIndex <= 0)
|
|
12
|
+
return { stem: trimmed, ext: '' };
|
|
13
|
+
return {
|
|
14
|
+
stem: trimmed.slice(0, dotIndex),
|
|
15
|
+
ext: trimmed.slice(dotIndex)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function stripAssetPrefix(stem, assetId) {
|
|
19
|
+
const trimmedStem = String(stem || '').trim();
|
|
20
|
+
const trimmedAssetId = String(assetId || '').trim();
|
|
21
|
+
if (!trimmedStem)
|
|
22
|
+
return '';
|
|
23
|
+
if (trimmedAssetId && trimmedStem.startsWith(`${trimmedAssetId}-`)) {
|
|
24
|
+
return trimmedStem.slice(trimmedAssetId.length + 1);
|
|
25
|
+
}
|
|
26
|
+
return trimmedStem.replace(/^asset-[a-z0-9-]+-/i, '');
|
|
27
|
+
}
|
|
28
|
+
function humanizeStem(stem) {
|
|
29
|
+
return String(stem || '')
|
|
30
|
+
.replace(/-\d{13,}$/g, '')
|
|
31
|
+
.replace(/[_-]+/g, ' ')
|
|
32
|
+
.replace(/\s+/g, ' ')
|
|
33
|
+
.trim();
|
|
34
|
+
}
|
|
35
|
+
function deriveNameFromFilename(filename, assetId) {
|
|
36
|
+
const { stem, ext } = splitExtension(basename(filename));
|
|
37
|
+
const strippedStem = stripAssetPrefix(stem, assetId);
|
|
38
|
+
const humanizedStem = humanizeStem(strippedStem || stem);
|
|
39
|
+
if (!humanizedStem)
|
|
40
|
+
return basename(filename) || 'Untitled document';
|
|
41
|
+
return `${humanizedStem}${ext}`;
|
|
42
|
+
}
|
|
43
|
+
export function isGeneratedDocumentName(value, assetId) {
|
|
44
|
+
const trimmed = String(value || '').trim();
|
|
45
|
+
if (!trimmed)
|
|
46
|
+
return true;
|
|
47
|
+
const normalized = basename(trimmed);
|
|
48
|
+
const { stem } = splitExtension(normalized);
|
|
49
|
+
const trimmedAssetId = String(assetId || '').trim();
|
|
50
|
+
if (trimmedAssetId && stem.toLowerCase() === trimmedAssetId.toLowerCase()) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
const strippedStem = stripAssetPrefix(stem, assetId);
|
|
54
|
+
if (!strippedStem)
|
|
55
|
+
return true;
|
|
56
|
+
return strippedStem !== stem;
|
|
57
|
+
}
|
|
58
|
+
export function getCanonicalDocumentName(input) {
|
|
59
|
+
const logicalName = String(input.logicalName || '').trim();
|
|
60
|
+
if (logicalName && !isGeneratedDocumentName(logicalName, input.assetId)) {
|
|
61
|
+
return logicalName;
|
|
62
|
+
}
|
|
63
|
+
const displayName = String(input.displayName || '').trim();
|
|
64
|
+
if (displayName && !isGeneratedDocumentName(displayName, input.assetId)) {
|
|
65
|
+
return displayName;
|
|
66
|
+
}
|
|
67
|
+
const title = String(input.title || '').trim();
|
|
68
|
+
if (title && !isGeneratedDocumentName(title, input.assetId)) {
|
|
69
|
+
return title;
|
|
70
|
+
}
|
|
71
|
+
const originalFilename = String(input.originalFilename || '').trim();
|
|
72
|
+
if (originalFilename)
|
|
73
|
+
return deriveNameFromFilename(originalFilename, input.assetId);
|
|
74
|
+
const pathName = String(input.fsPath || '').trim();
|
|
75
|
+
if (pathName)
|
|
76
|
+
return deriveNameFromFilename(pathName, input.assetId);
|
|
77
|
+
return 'Untitled document';
|
|
78
|
+
}
|
|
79
|
+
export function getReadableDocumentName(doc) {
|
|
80
|
+
return getCanonicalDocumentName(doc);
|
|
81
|
+
}
|
|
82
|
+
export function getDocumentDownloadName(doc) {
|
|
83
|
+
const readableName = getReadableDocumentName(doc);
|
|
84
|
+
const filenameSource = String(doc.originalFilename || doc.fsPath || '').trim();
|
|
85
|
+
const sourceExt = splitExtension(basename(filenameSource)).ext;
|
|
86
|
+
if (!sourceExt)
|
|
87
|
+
return readableName;
|
|
88
|
+
return readableName.toLowerCase().endsWith(sourceExt.toLowerCase())
|
|
89
|
+
? readableName
|
|
90
|
+
: `${readableName}${sourceExt}`;
|
|
91
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const DOCUMENT_REFERENCE_PREFIX = "D-";
|
|
2
|
+
export declare function formatDocumentReference(value: number | {
|
|
3
|
+
referenceNumber?: number | null;
|
|
4
|
+
} | null | undefined): string;
|
|
5
|
+
export declare function parseDocumentReference(value: string | null | undefined): number | null;
|
|
6
|
+
export declare function getDocumentReferenceLabel(entity: {
|
|
7
|
+
referenceNumber?: number | null;
|
|
8
|
+
referenceLabel?: string | null;
|
|
9
|
+
} | null | undefined): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { formatEntityReference, getEntityReferenceLabel, parseEntityReference } from './entityReferences.js';
|
|
2
|
+
export const DOCUMENT_REFERENCE_PREFIX = 'D-';
|
|
3
|
+
export function formatDocumentReference(value) {
|
|
4
|
+
return formatEntityReference(DOCUMENT_REFERENCE_PREFIX, value);
|
|
5
|
+
}
|
|
6
|
+
export function parseDocumentReference(value) {
|
|
7
|
+
return parseEntityReference(DOCUMENT_REFERENCE_PREFIX, value);
|
|
8
|
+
}
|
|
9
|
+
export function getDocumentReferenceLabel(entity) {
|
|
10
|
+
return getEntityReferenceLabel(DOCUMENT_REFERENCE_PREFIX, entity);
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function normalizeEntityReferenceNumber(value: unknown): number | null;
|
|
2
|
+
export declare function formatEntityReference(prefix: string, value: number | {
|
|
3
|
+
referenceNumber?: number | null;
|
|
4
|
+
} | null | undefined): string;
|
|
5
|
+
export declare function parseEntityReference(prefix: string, value: string | null | undefined): number | null;
|
|
6
|
+
export declare function getEntityReferenceLabel(prefix: string, entity: {
|
|
7
|
+
referenceNumber?: number | null;
|
|
8
|
+
referenceLabel?: string | null;
|
|
9
|
+
} | null | undefined): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function normalizeEntityReferenceNumber(value) {
|
|
2
|
+
const numeric = typeof value === 'number' ? value : Number(value);
|
|
3
|
+
if (!Number.isFinite(numeric))
|
|
4
|
+
return null;
|
|
5
|
+
const normalized = Math.floor(numeric);
|
|
6
|
+
return normalized > 0 ? normalized : null;
|
|
7
|
+
}
|
|
8
|
+
export function formatEntityReference(prefix, value) {
|
|
9
|
+
const referenceNumber = typeof value === 'object' && value !== null
|
|
10
|
+
? normalizeEntityReferenceNumber(value.referenceNumber)
|
|
11
|
+
: normalizeEntityReferenceNumber(value);
|
|
12
|
+
return referenceNumber ? `${prefix}${referenceNumber}` : '';
|
|
13
|
+
}
|
|
14
|
+
export function parseEntityReference(prefix, value) {
|
|
15
|
+
const normalizedPrefix = String(prefix || '').trim();
|
|
16
|
+
const normalizedValue = String(value || '').trim();
|
|
17
|
+
if (!normalizedPrefix || !normalizedValue)
|
|
18
|
+
return null;
|
|
19
|
+
const escapedPrefix = normalizedPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
20
|
+
const match = normalizedValue.match(new RegExp(`^${escapedPrefix}(\\d+)$`, 'i'));
|
|
21
|
+
if (!match)
|
|
22
|
+
return null;
|
|
23
|
+
return normalizeEntityReferenceNumber(match[1]);
|
|
24
|
+
}
|
|
25
|
+
export function getEntityReferenceLabel(prefix, entity) {
|
|
26
|
+
if (!entity)
|
|
27
|
+
return '';
|
|
28
|
+
if (typeof entity.referenceLabel === 'string' && entity.referenceLabel.trim().length > 0) {
|
|
29
|
+
return entity.referenceLabel.trim();
|
|
30
|
+
}
|
|
31
|
+
return formatEntityReference(prefix, entity.referenceNumber);
|
|
32
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const IMAGE_REFERENCE_PREFIX = "I-";
|
|
2
|
+
export declare function formatImageReference(value: number | {
|
|
3
|
+
referenceNumber?: number | null;
|
|
4
|
+
} | null | undefined): string;
|
|
5
|
+
export declare function parseImageReference(value: string | null | undefined): number | null;
|
|
6
|
+
export declare function getImageReferenceLabel(entity: {
|
|
7
|
+
referenceNumber?: number | null;
|
|
8
|
+
referenceLabel?: string | null;
|
|
9
|
+
} | null | undefined): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { formatEntityReference, getEntityReferenceLabel, parseEntityReference } from './entityReferences.js';
|
|
2
|
+
export const IMAGE_REFERENCE_PREFIX = 'I-';
|
|
3
|
+
export function formatImageReference(value) {
|
|
4
|
+
return formatEntityReference(IMAGE_REFERENCE_PREFIX, value);
|
|
5
|
+
}
|
|
6
|
+
export function parseImageReference(value) {
|
|
7
|
+
return parseEntityReference(IMAGE_REFERENCE_PREFIX, value);
|
|
8
|
+
}
|
|
9
|
+
export function getImageReferenceLabel(entity) {
|
|
10
|
+
return getEntityReferenceLabel(IMAGE_REFERENCE_PREFIX, entity);
|
|
11
|
+
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Parses a markdown implementation plan into a structured task tree.
|
|
4
4
|
* Pure function — no I/O, no side effects.
|
|
5
5
|
*/
|
|
6
|
-
export type ParsedTaskType = '
|
|
7
|
-
export type ParsedTaskPriority = 1 | 2 | 3
|
|
6
|
+
export type ParsedTaskType = 'task' | 'deliverable' | 'issue' | 'idea' | 'review';
|
|
7
|
+
export type ParsedTaskPriority = 1 | 2 | 3;
|
|
8
8
|
export interface ParsedTask {
|
|
9
9
|
/** Stable key for idempotent generation — derived from title + depth */
|
|
10
10
|
idempotencyKey: string;
|
package/dist/utils/planParser.js
CHANGED
|
@@ -6,22 +6,22 @@
|
|
|
6
6
|
// ─── Inference helpers ──────────────────────────────────────────────────────
|
|
7
7
|
function inferType(title) {
|
|
8
8
|
const l = title.toLowerCase();
|
|
9
|
-
if (/\b(bug|fix|fixes|fixed|broken|
|
|
10
|
-
return '
|
|
11
|
-
if (/\b(
|
|
12
|
-
return '
|
|
13
|
-
if (/\b(
|
|
14
|
-
return '
|
|
15
|
-
if (/\b(
|
|
16
|
-
return '
|
|
17
|
-
return '
|
|
9
|
+
if (/\b(bug|fix|fixes|fixed|broken|regression|hotfix|incident|blocker)\b/.test(l))
|
|
10
|
+
return 'issue';
|
|
11
|
+
if (/\b(review|approve|approval|qa|test|testing|audit|verify|validation)\b/.test(l))
|
|
12
|
+
return 'review';
|
|
13
|
+
if (/\b(idea|brainstorm|prototype|spike|explor|experiment)\b/.test(l))
|
|
14
|
+
return 'idea';
|
|
15
|
+
if (/\b(doc|docs|documentation|readme|changelog|comment|comments|spec|design|copy|wireframe|mockup|asset|content)\b/.test(l))
|
|
16
|
+
return 'deliverable';
|
|
17
|
+
return 'task';
|
|
18
18
|
}
|
|
19
19
|
function inferPriority(title) {
|
|
20
20
|
const l = title.toLowerCase();
|
|
21
|
-
if (/\b(critical|blocker|p0|urgent)\b/.test(l))
|
|
22
|
-
return 4;
|
|
23
21
|
if (/\b(high|important|p1)\b/.test(l))
|
|
24
22
|
return 3;
|
|
23
|
+
if (/\b(critical|blocker|p0|urgent)\b/.test(l))
|
|
24
|
+
return 3;
|
|
25
25
|
if (/\b(low|minor|nice.?to.?have|p3)\b/.test(l))
|
|
26
26
|
return 1;
|
|
27
27
|
return 2;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { parsePlan, flattenSelected } from '
|
|
2
|
+
import { parsePlan, flattenSelected } from './planParser';
|
|
3
3
|
// ─── parsePlan ───────────────────────────────────────────────────────────────
|
|
4
4
|
describe('parsePlan', () => {
|
|
5
5
|
it('returns empty array for empty content', () => {
|
|
@@ -72,27 +72,27 @@ describe('parsePlan — type inference', () => {
|
|
|
72
72
|
function typeOf(title) {
|
|
73
73
|
return parsePlan(`## ${title}`)[0].type;
|
|
74
74
|
}
|
|
75
|
-
it('infers "
|
|
76
|
-
expect(typeOf('Fix login bug')).toBe('
|
|
77
|
-
expect(typeOf('Bug: broken redirect')).toBe('
|
|
78
|
-
expect(typeOf('Hotfix for session issue')).toBe('
|
|
75
|
+
it('infers "issue" for fix/bug keywords', () => {
|
|
76
|
+
expect(typeOf('Fix login bug')).toBe('issue');
|
|
77
|
+
expect(typeOf('Bug: broken redirect')).toBe('issue');
|
|
78
|
+
expect(typeOf('Hotfix for session issue')).toBe('issue');
|
|
79
79
|
});
|
|
80
|
-
it('
|
|
81
|
-
expect(typeOf('Refactor auth module')).toBe('
|
|
82
|
-
expect(typeOf('Clean up legacy routes')).toBe('
|
|
80
|
+
it('defaults refactor/cleanup work to "task"', () => {
|
|
81
|
+
expect(typeOf('Refactor auth module')).toBe('task');
|
|
82
|
+
expect(typeOf('Clean up legacy routes')).toBe('task');
|
|
83
83
|
});
|
|
84
|
-
it('infers "
|
|
85
|
-
expect(typeOf('Update README')).toBe('
|
|
86
|
-
expect(typeOf('Write docs for API')).toBe('
|
|
84
|
+
it('infers "deliverable" for docs keywords', () => {
|
|
85
|
+
expect(typeOf('Update README')).toBe('deliverable');
|
|
86
|
+
expect(typeOf('Write docs for API')).toBe('deliverable');
|
|
87
87
|
});
|
|
88
|
-
it('
|
|
89
|
-
expect(typeOf('Setup CI pipeline')).toBe('
|
|
90
|
-
expect(typeOf('Config environment')).toBe('
|
|
91
|
-
expect(typeOf('Deploy infrastructure')).toBe('
|
|
88
|
+
it('defaults to "task" for setup/config/deploy keywords', () => {
|
|
89
|
+
expect(typeOf('Setup CI pipeline')).toBe('task');
|
|
90
|
+
expect(typeOf('Config environment')).toBe('task');
|
|
91
|
+
expect(typeOf('Deploy infrastructure')).toBe('task');
|
|
92
92
|
});
|
|
93
|
-
it('defaults to "
|
|
94
|
-
expect(typeOf('Add user dashboard')).toBe('
|
|
95
|
-
expect(typeOf('Phase 1 — Core Module')).toBe('
|
|
93
|
+
it('defaults to "task" for unrecognised titles', () => {
|
|
94
|
+
expect(typeOf('Add user dashboard')).toBe('task');
|
|
95
|
+
expect(typeOf('Phase 1 — Core Module')).toBe('task');
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
// ─── Priority inference ──────────────────────────────────────────────────────
|
|
@@ -100,10 +100,10 @@ describe('parsePlan — priority inference', () => {
|
|
|
100
100
|
function priorityOf(title) {
|
|
101
101
|
return parsePlan(`## ${title}`)[0].priority;
|
|
102
102
|
}
|
|
103
|
-
it('
|
|
104
|
-
expect(priorityOf('Critical: auth bypass')).toBe(
|
|
105
|
-
expect(priorityOf('Blocker — build fails')).toBe(
|
|
106
|
-
expect(priorityOf('P0 fix needed')).toBe(
|
|
103
|
+
it('maps "critical" / "blocker" / "p0" to the highest 3-level priority', () => {
|
|
104
|
+
expect(priorityOf('Critical: auth bypass')).toBe(3);
|
|
105
|
+
expect(priorityOf('Blocker — build fails')).toBe(3);
|
|
106
|
+
expect(priorityOf('P0 fix needed')).toBe(3);
|
|
107
107
|
});
|
|
108
108
|
it('infers priority 3 (High) for "high" / "important"', () => {
|
|
109
109
|
expect(priorityOf('High priority task')).toBe(3);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type ReferenceLike = {
|
|
2
|
+
referenceNumber?: number | null;
|
|
3
|
+
referenceLabel?: string | null;
|
|
4
|
+
};
|
|
5
|
+
export declare const WORKSTREAM_REFERENCE_PREFIX = "WS-";
|
|
6
|
+
export declare const INITIATIVE_REFERENCE_PREFIX = "IN-";
|
|
7
|
+
export declare function formatWorkstreamReference(value: number | ReferenceLike | null | undefined): string;
|
|
8
|
+
export declare function parseWorkstreamReference(value: string | null | undefined): number | null;
|
|
9
|
+
export declare function getWorkstreamReferenceLabel(workstream: ReferenceLike | null | undefined): string;
|
|
10
|
+
export declare function formatInitiativeReference(value: number | ReferenceLike | null | undefined): string;
|
|
11
|
+
export declare function parseInitiativeReference(value: string | null | undefined): number | null;
|
|
12
|
+
export declare function getInitiativeReferenceLabel(initiative: ReferenceLike | null | undefined): string;
|
|
13
|
+
type InitiativeReferenceLike = ReferenceLike & {
|
|
14
|
+
id: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function resolveInitiativeReference<T extends InitiativeReferenceLike>(initiatives: T[], value: string | null | undefined): T | null;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { formatEntityReference, getEntityReferenceLabel, parseEntityReference, } from './entityReferences.js';
|
|
2
|
+
export const WORKSTREAM_REFERENCE_PREFIX = 'WS-';
|
|
3
|
+
export const INITIATIVE_REFERENCE_PREFIX = 'IN-';
|
|
4
|
+
export function formatWorkstreamReference(value) {
|
|
5
|
+
return formatEntityReference(WORKSTREAM_REFERENCE_PREFIX, value);
|
|
6
|
+
}
|
|
7
|
+
export function parseWorkstreamReference(value) {
|
|
8
|
+
return parseEntityReference(WORKSTREAM_REFERENCE_PREFIX, value);
|
|
9
|
+
}
|
|
10
|
+
export function getWorkstreamReferenceLabel(workstream) {
|
|
11
|
+
return getEntityReferenceLabel(WORKSTREAM_REFERENCE_PREFIX, workstream);
|
|
12
|
+
}
|
|
13
|
+
export function formatInitiativeReference(value) {
|
|
14
|
+
return formatEntityReference(INITIATIVE_REFERENCE_PREFIX, value);
|
|
15
|
+
}
|
|
16
|
+
export function parseInitiativeReference(value) {
|
|
17
|
+
return parseEntityReference(INITIATIVE_REFERENCE_PREFIX, value);
|
|
18
|
+
}
|
|
19
|
+
export function getInitiativeReferenceLabel(initiative) {
|
|
20
|
+
return getEntityReferenceLabel(INITIATIVE_REFERENCE_PREFIX, initiative);
|
|
21
|
+
}
|
|
22
|
+
export function resolveInitiativeReference(initiatives, value) {
|
|
23
|
+
const normalized = String(value || '').trim();
|
|
24
|
+
if (!normalized)
|
|
25
|
+
return null;
|
|
26
|
+
const exactReferenceNumber = parseInitiativeReference(normalized);
|
|
27
|
+
return initiatives.find((initiative) => (initiative.id === normalized
|
|
28
|
+
|| formatInitiativeReference(initiative) === normalized
|
|
29
|
+
|| (exactReferenceNumber !== null && initiative.referenceNumber === exactReferenceNumber))) || null;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { formatInitiativeReference, resolveInitiativeReference, } from './planningReferences';
|
|
3
|
+
describe('planningReferences', () => {
|
|
4
|
+
const initiatives = [
|
|
5
|
+
{ id: 'initiative-1', referenceNumber: 1, title: 'Alpha' },
|
|
6
|
+
{ id: 'initiative-2', referenceNumber: 2, title: 'Beta' },
|
|
7
|
+
];
|
|
8
|
+
it('resolves initiative references by id and formatted label', () => {
|
|
9
|
+
expect(resolveInitiativeReference(initiatives, 'initiative-1')?.id).toBe('initiative-1');
|
|
10
|
+
expect(resolveInitiativeReference(initiatives, formatInitiativeReference(initiatives[1]))?.id).toBe('initiative-2');
|
|
11
|
+
});
|
|
12
|
+
it('returns null for empty or invalid initiative references', () => {
|
|
13
|
+
expect(resolveInitiativeReference(initiatives, '')).toBeNull();
|
|
14
|
+
expect(resolveInitiativeReference(initiatives, 'IN-999')).toBeNull();
|
|
15
|
+
expect(resolveInitiativeReference(initiatives, 'not-a-reference')).toBeNull();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TaskActivityItem, TaskEvent, TaskItem } from '../types';
|
|
2
|
+
export type TaskEventValueFormatter = (field: string, value: unknown) => string | undefined;
|
|
3
|
+
export declare function summarizeTaskChange(field: string, change: {
|
|
4
|
+
from?: unknown;
|
|
5
|
+
to?: unknown;
|
|
6
|
+
} | undefined, formatter?: TaskEventValueFormatter): string;
|
|
7
|
+
export declare function summarizeTaskEvent(event: TaskEvent, formatter?: TaskEventValueFormatter): string;
|
|
8
|
+
export declare function getLatestTaskActivity(task: Pick<TaskItem, 'activity' | 'comments'>): TaskActivityItem | null;
|
|
9
|
+
export declare function summarizeTaskActivity(item: TaskActivityItem | null, formatter?: TaskEventValueFormatter): string;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
function formatValue(value, field, formatter) {
|
|
2
|
+
const formatted = formatter?.(field, value);
|
|
3
|
+
if (typeof formatted === 'string')
|
|
4
|
+
return formatted;
|
|
5
|
+
if (value === null || value === undefined || value === '')
|
|
6
|
+
return 'none';
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
const normalized = value.map((entry) => formatValue(entry, field, formatter)).filter(Boolean);
|
|
9
|
+
return normalized.length > 0 ? normalized.join(', ') : 'none';
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === 'object')
|
|
12
|
+
return 'updated';
|
|
13
|
+
return String(value);
|
|
14
|
+
}
|
|
15
|
+
function normalizeChecklistItems(value) {
|
|
16
|
+
if (!Array.isArray(value))
|
|
17
|
+
return [];
|
|
18
|
+
return value.map((entry, index) => {
|
|
19
|
+
const item = (entry && typeof entry === 'object' ? entry : {});
|
|
20
|
+
const orderValue = Number(item.order);
|
|
21
|
+
return {
|
|
22
|
+
id: String(item.id || '').trim(),
|
|
23
|
+
title: String(item.title || '').trim(),
|
|
24
|
+
isCompleted: Boolean(item.isCompleted),
|
|
25
|
+
order: Number.isFinite(orderValue) ? orderValue : index,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function summarizeChecklistChange(change) {
|
|
30
|
+
const before = normalizeChecklistItems(change?.from);
|
|
31
|
+
const after = normalizeChecklistItems(change?.to);
|
|
32
|
+
const beforeById = new Map(before.map((item) => [item.id || item.title, item]));
|
|
33
|
+
const afterById = new Map(after.map((item) => [item.id || item.title, item]));
|
|
34
|
+
for (const [key, nextItem] of afterById.entries()) {
|
|
35
|
+
const prevItem = beforeById.get(key);
|
|
36
|
+
if (!prevItem) {
|
|
37
|
+
return nextItem.title ? `Checklist item added: ${nextItem.title}` : 'Checklist item added';
|
|
38
|
+
}
|
|
39
|
+
if (prevItem.isCompleted !== nextItem.isCompleted) {
|
|
40
|
+
if (nextItem.title) {
|
|
41
|
+
return nextItem.isCompleted
|
|
42
|
+
? `Checklist item completed: ${nextItem.title}`
|
|
43
|
+
: `Checklist item reopened: ${nextItem.title}`;
|
|
44
|
+
}
|
|
45
|
+
return nextItem.isCompleted ? 'Checklist item completed' : 'Checklist item reopened';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const [key, prevItem] of beforeById.entries()) {
|
|
49
|
+
if (!afterById.has(key)) {
|
|
50
|
+
return prevItem.title ? `Checklist item removed: ${prevItem.title}` : 'Checklist item removed';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const sameMembership = before.length === after.length
|
|
54
|
+
&& before.every((item) => afterById.has(item.id || item.title));
|
|
55
|
+
if (sameMembership) {
|
|
56
|
+
const orderChanged = before.some((item, index) => {
|
|
57
|
+
const nextItem = after[index];
|
|
58
|
+
return (item.id || item.title) !== (nextItem?.id || nextItem?.title);
|
|
59
|
+
});
|
|
60
|
+
if (orderChanged)
|
|
61
|
+
return 'Checklist reordered';
|
|
62
|
+
}
|
|
63
|
+
return 'Checklist updated';
|
|
64
|
+
}
|
|
65
|
+
export function summarizeTaskChange(field, change, formatter) {
|
|
66
|
+
if (field === 'checklistItems') {
|
|
67
|
+
return summarizeChecklistChange(change);
|
|
68
|
+
}
|
|
69
|
+
if (field === 'description') {
|
|
70
|
+
const hadBefore = formatValue(change?.from, field, formatter) !== 'none';
|
|
71
|
+
const hasAfter = formatValue(change?.to, field, formatter) !== 'none';
|
|
72
|
+
if (!hadBefore && hasAfter)
|
|
73
|
+
return 'Description added';
|
|
74
|
+
if (hadBefore && !hasAfter)
|
|
75
|
+
return 'Description cleared';
|
|
76
|
+
return 'Description updated';
|
|
77
|
+
}
|
|
78
|
+
return `${field}: ${formatValue(change?.from, field, formatter)} -> ${formatValue(change?.to, field, formatter)}`;
|
|
79
|
+
}
|
|
80
|
+
export function summarizeTaskEvent(event, formatter) {
|
|
81
|
+
const changes = event.details?.changes || {};
|
|
82
|
+
const fields = Object.keys(changes);
|
|
83
|
+
if (event.action === 'task-created')
|
|
84
|
+
return 'Task created';
|
|
85
|
+
if (event.action === 'task-comment-added')
|
|
86
|
+
return 'Comment added';
|
|
87
|
+
if (event.action === 'task-archived')
|
|
88
|
+
return 'Task marked done';
|
|
89
|
+
if (event.action === 'task-cancelled')
|
|
90
|
+
return 'Task cancelled';
|
|
91
|
+
if (event.action === 'task-unarchived')
|
|
92
|
+
return 'Task restored';
|
|
93
|
+
if (event.action === 'task-status-changed' && changes.status) {
|
|
94
|
+
return `Status: ${formatValue(changes.status.from, 'status', formatter)} -> ${formatValue(changes.status.to, 'status', formatter)}`;
|
|
95
|
+
}
|
|
96
|
+
if (event.action === 'task-schedule-changed') {
|
|
97
|
+
if (changes.scheduledDate) {
|
|
98
|
+
return `Scheduled: ${formatValue(changes.scheduledDate.from, 'scheduledDate', formatter)} -> ${formatValue(changes.scheduledDate.to, 'scheduledDate', formatter)}`;
|
|
99
|
+
}
|
|
100
|
+
if (changes.dueDate) {
|
|
101
|
+
return `Due: ${formatValue(changes.dueDate.from, 'dueDate', formatter)} -> ${formatValue(changes.dueDate.to, 'dueDate', formatter)}`;
|
|
102
|
+
}
|
|
103
|
+
return 'Schedule updated';
|
|
104
|
+
}
|
|
105
|
+
if (event.action === 'task-relationship-changed' && changes.workstreamId) {
|
|
106
|
+
return `Workstream: ${formatValue(changes.workstreamId.from, 'workstreamId', formatter)} -> ${formatValue(changes.workstreamId.to, 'workstreamId', formatter)}`;
|
|
107
|
+
}
|
|
108
|
+
if (event.action === 'task-attachments-changed')
|
|
109
|
+
return 'Attachments updated';
|
|
110
|
+
if (fields.length === 1) {
|
|
111
|
+
const field = fields[0];
|
|
112
|
+
const change = changes[field];
|
|
113
|
+
return summarizeTaskChange(field, change, formatter);
|
|
114
|
+
}
|
|
115
|
+
if (fields.length > 1)
|
|
116
|
+
return `${fields.length} fields updated`;
|
|
117
|
+
return 'Task updated';
|
|
118
|
+
}
|
|
119
|
+
export function getLatestTaskActivity(task) {
|
|
120
|
+
const items = Array.isArray(task.activity) && task.activity.length > 0
|
|
121
|
+
? task.activity
|
|
122
|
+
: Array.isArray(task.comments)
|
|
123
|
+
? task.comments.map((comment) => ({
|
|
124
|
+
id: `comment:${comment.id}`,
|
|
125
|
+
type: 'comment',
|
|
126
|
+
timestamp: comment.timestamp,
|
|
127
|
+
comment
|
|
128
|
+
}))
|
|
129
|
+
: [];
|
|
130
|
+
if (items.length === 0)
|
|
131
|
+
return null;
|
|
132
|
+
return [...items].sort((left, right) => {
|
|
133
|
+
const leftTs = Date.parse(String(left.timestamp || ''));
|
|
134
|
+
const rightTs = Date.parse(String(right.timestamp || ''));
|
|
135
|
+
if (Number.isFinite(leftTs) && Number.isFinite(rightTs) && leftTs !== rightTs) {
|
|
136
|
+
return rightTs - leftTs;
|
|
137
|
+
}
|
|
138
|
+
return String(right.id || '').localeCompare(String(left.id || ''));
|
|
139
|
+
})[0] || null;
|
|
140
|
+
}
|
|
141
|
+
export function summarizeTaskActivity(item, formatter) {
|
|
142
|
+
if (!item)
|
|
143
|
+
return '';
|
|
144
|
+
if (item.type === 'comment')
|
|
145
|
+
return item.comment.text;
|
|
146
|
+
return summarizeTaskEvent(item.event, formatter);
|
|
147
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { summarizeTaskChange } from './taskActivity';
|
|
3
|
+
describe('summarizeTaskChange', () => {
|
|
4
|
+
it('summarizes checklist completion clearly', () => {
|
|
5
|
+
expect(summarizeTaskChange('checklistItems', {
|
|
6
|
+
from: [{ id: 'a', title: 'First item', isCompleted: false, order: 0 }],
|
|
7
|
+
to: [{ id: 'a', title: 'First item', isCompleted: true, order: 0 }],
|
|
8
|
+
})).toBe('Checklist item completed: First item');
|
|
9
|
+
});
|
|
10
|
+
it('summarizes checklist additions clearly', () => {
|
|
11
|
+
expect(summarizeTaskChange('checklistItems', {
|
|
12
|
+
from: [],
|
|
13
|
+
to: [{ id: 'a', title: 'First item', isCompleted: false, order: 0 }],
|
|
14
|
+
})).toBe('Checklist item added: First item');
|
|
15
|
+
});
|
|
16
|
+
it('summarizes checklist removals clearly', () => {
|
|
17
|
+
expect(summarizeTaskChange('checklistItems', {
|
|
18
|
+
from: [{ id: 'a', title: 'First item', isCompleted: false, order: 0 }],
|
|
19
|
+
to: [],
|
|
20
|
+
})).toBe('Checklist item removed: First item');
|
|
21
|
+
});
|
|
22
|
+
it('summarizes checklist reorder clearly', () => {
|
|
23
|
+
expect(summarizeTaskChange('checklistItems', {
|
|
24
|
+
from: [
|
|
25
|
+
{ id: 'a', title: 'First item', isCompleted: false, order: 0 },
|
|
26
|
+
{ id: 'b', title: 'Second item', isCompleted: false, order: 1 },
|
|
27
|
+
],
|
|
28
|
+
to: [
|
|
29
|
+
{ id: 'b', title: 'Second item', isCompleted: false, order: 0 },
|
|
30
|
+
{ id: 'a', title: 'First item', isCompleted: false, order: 1 },
|
|
31
|
+
],
|
|
32
|
+
})).toBe('Checklist reordered');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CategoryConfig, TaskAssignee, TaskStatus } from '../types';
|
|
2
|
+
type ApproachOption = {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
};
|
|
6
|
+
export interface DraftDefaultsForGrouping {
|
|
7
|
+
category?: string;
|
|
8
|
+
type?: string;
|
|
9
|
+
priority?: number;
|
|
10
|
+
complexity?: number;
|
|
11
|
+
approach?: string;
|
|
12
|
+
taxonomyApproach?: string;
|
|
13
|
+
assignee?: TaskAssignee;
|
|
14
|
+
status?: TaskStatus;
|
|
15
|
+
scheduledDate?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveDraftDefaultsForGrouping(groupField: string, value: string | number, options: {
|
|
18
|
+
categories: CategoryConfig[];
|
|
19
|
+
approaches: ApproachOption[];
|
|
20
|
+
}): DraftDefaultsForGrouping;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export function resolveDraftDefaultsForGrouping(groupField, value, options) {
|
|
2
|
+
const normalizedValue = String(value);
|
|
3
|
+
if (groupField === 'category') {
|
|
4
|
+
const match = options.categories.find((category) => String(category.value) === normalizedValue || category.label === normalizedValue);
|
|
5
|
+
return match ? { category: match.label } : {};
|
|
6
|
+
}
|
|
7
|
+
if (groupField === 'type') {
|
|
8
|
+
return { type: normalizedValue };
|
|
9
|
+
}
|
|
10
|
+
if (groupField === 'priority') {
|
|
11
|
+
return Number.isFinite(Number(value)) ? { priority: Number(value) } : {};
|
|
12
|
+
}
|
|
13
|
+
if (groupField === 'complexity') {
|
|
14
|
+
return Number.isFinite(Number(value)) ? { complexity: Number(value) } : {};
|
|
15
|
+
}
|
|
16
|
+
if (groupField === 'approach') {
|
|
17
|
+
const match = options.approaches.find((approach) => String(approach.value) === normalizedValue || approach.label === normalizedValue);
|
|
18
|
+
return match ? { approach: match.value, taxonomyApproach: match.value } : {};
|
|
19
|
+
}
|
|
20
|
+
if (groupField === 'assignee') {
|
|
21
|
+
if (normalizedValue.trim().length > 0) {
|
|
22
|
+
return { assignee: normalizedValue };
|
|
23
|
+
}
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
if (groupField === 'status') {
|
|
27
|
+
if (normalizedValue === 'completed')
|
|
28
|
+
return { status: 'done' };
|
|
29
|
+
if (normalizedValue === 'task' || normalizedValue === 'on-hold' || normalizedValue === 'in-progress' || normalizedValue === 'review' || normalizedValue === 'done' || normalizedValue === 'cancelled') {
|
|
30
|
+
return { status: normalizedValue };
|
|
31
|
+
}
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
if (groupField === 'schedule') {
|
|
35
|
+
if (normalizedValue === 'backlog' || normalizedValue === 'expired')
|
|
36
|
+
return {};
|
|
37
|
+
return { scheduledDate: normalizedValue };
|
|
38
|
+
}
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|