@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.
Files changed (696) hide show
  1. package/README.md +52 -21
  2. package/dist/Taskforce.module.css +3394 -5981
  3. package/dist/TaskforceCore.CategoryFallback.test.js +5 -2
  4. package/dist/TaskforceCore.filter-persistence.test.js +402 -0
  5. package/dist/TaskforceCore.js +388 -71
  6. package/dist/TaskforceCore.routing.test.js +311 -0
  7. package/dist/TaskforceCore.test.js +3344 -615
  8. package/dist/TaskforceWidget.js +3 -2
  9. package/dist/__tests__/localizationCatalogs.test.js +48 -31
  10. package/dist/__tests__/workflowSimulation.test.js +2 -2
  11. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +60 -0
  12. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +324 -0
  13. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.js +278 -0
  14. package/dist/annotatedAttachments/payload.d.ts +2 -0
  15. package/dist/annotatedAttachments/payload.js +54 -0
  16. package/dist/annotatedAttachments/payload.test.js +67 -0
  17. package/dist/annotatedAttachments/service.d.ts +49 -0
  18. package/dist/annotatedAttachments/service.js +121 -0
  19. package/dist/annotatedAttachments/types.d.ts +86 -0
  20. package/dist/cli.js +74 -25
  21. package/dist/compat/deploymentCompat.d.ts +12 -0
  22. package/dist/compat/deploymentCompat.js +43 -0
  23. package/dist/compat/workspaceSyncCompat.d.ts +6 -0
  24. package/dist/compat/workspaceSyncCompat.js +79 -0
  25. package/dist/compat/workspaceSyncCompat.test.js +87 -0
  26. package/dist/components/features/AgentsModule.d.ts +5 -0
  27. package/dist/components/features/AgentsModule.js +131 -0
  28. package/dist/components/features/AgentsModule.test.js +102 -0
  29. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +24 -0
  30. package/dist/components/features/AnnotatedAttachmentWorkspace.js +1942 -0
  31. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +2831 -0
  32. package/dist/components/features/DocumentGenerateModal.js +8 -16
  33. package/dist/components/features/DocumentIndex.d.ts +3 -4
  34. package/dist/components/features/DocumentIndex.js +22 -10
  35. package/dist/components/features/DocumentViewer.d.ts +6 -2
  36. package/dist/components/features/DocumentViewer.js +1000 -18
  37. package/dist/components/features/DocumentWorkspace.d.ts +40 -2
  38. package/dist/components/features/DocumentWorkspace.js +96 -16
  39. package/dist/components/features/DocumentWorkspace.test.js +1202 -0
  40. package/dist/components/features/InitiativesModule.d.ts +22 -0
  41. package/dist/components/features/InitiativesModule.js +33 -0
  42. package/dist/components/features/TaskSettings.d.ts +41 -32
  43. package/dist/components/features/TaskSettings.js +798 -313
  44. package/dist/components/features/TaskSettings.test.js +1221 -47
  45. package/dist/components/features/WorkflowsModule.d.ts +27 -0
  46. package/dist/components/features/WorkflowsModule.js +21 -0
  47. package/dist/components/features/documentWorkspaceFilters.d.ts +10 -0
  48. package/dist/components/features/documentWorkspaceFilters.js +11 -0
  49. package/dist/components/features/settings/CategoryManager.d.ts +2 -0
  50. package/dist/components/features/settings/CategoryManager.js +15 -8
  51. package/dist/components/features/settings/PriorityManager.d.ts +18 -0
  52. package/dist/components/features/settings/PriorityManager.js +51 -0
  53. package/dist/components/features/settings/TaxonomyEditor.d.ts +2 -1
  54. package/dist/components/features/settings/TaxonomyEditor.js +41 -18
  55. package/dist/components/features/settings/TaxonomyLibraryManager.d.ts +26 -0
  56. package/dist/components/features/settings/TaxonomyLibraryManager.js +301 -0
  57. package/dist/components/features/settings/TaxonomyLibraryManager.test.js +141 -0
  58. package/dist/components/features/settings/TaxonomyManager.d.ts +35 -12
  59. package/dist/components/features/settings/TaxonomyManager.js +59 -27
  60. package/dist/components/features/settings/TypeManager.d.ts +11 -0
  61. package/dist/components/features/settings/TypeManager.js +48 -11
  62. package/dist/components/features/settings/{WorkflowEditorPrototype.d.ts → WorkflowEditor.d.ts} +2 -2
  63. package/dist/components/features/settings/{WorkflowEditorPrototype.js → WorkflowEditor.js} +3 -3
  64. package/dist/components/task/TaskActionHeader.d.ts +12 -2
  65. package/dist/components/task/TaskActionHeader.js +64 -8
  66. package/dist/components/task/TaskActionHeader.test.js +73 -0
  67. package/dist/components/task/TaskCard.d.ts +14 -16
  68. package/dist/components/task/TaskCard.js +144 -174
  69. package/dist/components/task/TaskCard.test.js +416 -64
  70. package/dist/components/task/TaskContextUpload.d.ts +6 -5
  71. package/dist/components/task/TaskContextUpload.js +199 -64
  72. package/dist/components/task/TaskContextUpload.test.js +331 -14
  73. package/dist/components/task/TaskForm.d.ts +23 -29
  74. package/dist/components/task/TaskForm.js +348 -169
  75. package/dist/components/task/TaskForm.test.js +419 -23
  76. package/dist/components/task/TaskKanban.d.ts +20 -21
  77. package/dist/components/task/TaskKanban.js +176 -316
  78. package/dist/components/task/TaskKanban.planning-drop.test.js +93 -0
  79. package/dist/components/task/TaskList.d.ts +22 -11
  80. package/dist/components/task/TaskList.js +98 -12
  81. package/dist/components/task/TaskList.test.js +206 -7
  82. package/dist/components/task/TaskReferenceBadge.d.ts +12 -0
  83. package/dist/components/task/TaskReferenceBadge.js +5 -0
  84. package/dist/components/task/TaskStatusActions.d.ts +12 -0
  85. package/dist/components/task/TaskStatusActions.js +18 -0
  86. package/dist/components/task/TaskStatusActions.test.js +45 -0
  87. package/dist/components/ui/ImageReferenceBadge.d.ts +12 -0
  88. package/dist/components/ui/ImageReferenceBadge.js +5 -0
  89. package/dist/components/ui/LevelSelector.d.ts +2 -1
  90. package/dist/components/ui/LevelSelector.js +2 -2
  91. package/dist/components/ui/Markdown.d.ts +1 -2
  92. package/dist/components/ui/Markdown.js +2 -13
  93. package/dist/components/ui/Modal.d.ts +3 -2
  94. package/dist/components/ui/Modal.js +4 -3
  95. package/dist/components/ui/MultiSelectFilter.d.ts +3 -1
  96. package/dist/components/ui/MultiSelectFilter.js +2 -2
  97. package/dist/components/ui/ReferenceBadgeButton.d.ts +13 -0
  98. package/dist/components/ui/ReferenceBadgeButton.js +6 -0
  99. package/dist/components/ui/TaxonomyDropdown.d.ts +7 -1
  100. package/dist/components/ui/TaxonomyDropdown.js +58 -23
  101. package/dist/components/ui/TopNoticeLayer.d.ts +7 -0
  102. package/dist/components/ui/TopNoticeLayer.js +14 -0
  103. package/dist/components/ui/TopNoticeLayer.test.js +25 -0
  104. package/dist/components/views/AppShellHeader.d.ts +13 -0
  105. package/dist/components/views/AppShellHeader.js +19 -0
  106. package/dist/components/views/AppShellHeader.test.js +21 -0
  107. package/dist/components/views/PlanComparisonPage.d.ts +73 -0
  108. package/dist/components/views/PlanComparisonPage.js +196 -0
  109. package/dist/components/views/PlanComparisonPage.test.js +251 -0
  110. package/dist/components/views/PlansPage.d.ts +14 -0
  111. package/dist/components/views/PlansPage.js +355 -0
  112. package/dist/components/views/StandaloneLayout.d.ts +2 -2
  113. package/dist/components/views/StandaloneLayout.js +2212 -1194
  114. package/dist/components/views/WidgetView.d.ts +2 -2
  115. package/dist/components/views/WidgetView.js +149 -43
  116. package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +57 -0
  117. package/dist/components/views/chrome/WorkspaceChromeSections.js +38 -0
  118. package/dist/components/views/chrome/WorkspaceChromeSections.test.js +54 -0
  119. package/dist/components/views/chrome/workspaceChrome.d.ts +31 -0
  120. package/dist/components/views/chrome/workspaceChrome.js +108 -0
  121. package/dist/components/views/chrome/workspaceChrome.test.js +52 -0
  122. package/dist/components/views/panels/DocumentFilterToolbar.d.ts +10 -0
  123. package/dist/components/views/panels/DocumentFilterToolbar.js +7 -0
  124. package/dist/components/views/panels/DocumentFilterToolbar.test.js +19 -0
  125. package/dist/components/views/panels/FilterToolbar.d.ts +66 -0
  126. package/dist/components/views/panels/FilterToolbar.js +21 -0
  127. package/dist/components/views/panels/FilterToolbar.test.d.ts +1 -0
  128. package/dist/components/views/panels/FilterToolbar.test.js +45 -0
  129. package/dist/components/views/panels/FilterToolbarControls.d.ts +46 -0
  130. package/dist/components/views/panels/FilterToolbarControls.js +61 -0
  131. package/dist/components/views/panels/PlanningDrawer.d.ts +115 -0
  132. package/dist/components/views/panels/PlanningDrawer.js +220 -0
  133. package/dist/components/views/panels/ScheduleSidebar.d.ts +52 -0
  134. package/dist/components/views/panels/ScheduleSidebar.js +127 -0
  135. package/dist/components/views/panels/scheduleUtils.d.ts +14 -0
  136. package/dist/components/views/panels/scheduleUtils.js +79 -0
  137. package/dist/components/views/teamManagementAccess.d.ts +6 -0
  138. package/dist/components/views/teamManagementAccess.js +18 -0
  139. package/dist/components/views/teamManagementAccess.test.d.ts +1 -0
  140. package/dist/components/views/teamManagementAccess.test.js +44 -0
  141. package/dist/config/clientDeployment.d.ts +2 -0
  142. package/dist/config/clientDeployment.js +13 -0
  143. package/dist/config/cloudEnvironment.d.ts +15 -0
  144. package/dist/config/cloudEnvironment.js +60 -0
  145. package/dist/config/deployment.d.ts +20 -0
  146. package/dist/config/deployment.js +67 -0
  147. package/dist/config/deployment.test.d.ts +1 -0
  148. package/dist/config/deployment.test.js +88 -0
  149. package/dist/config/envSchema.js +36 -8
  150. package/dist/config/envSchema.test.js +28 -0
  151. package/dist/core/AiProfileService.d.ts +66 -0
  152. package/dist/core/AiProfileService.js +320 -0
  153. package/dist/core/AiProfileService.test.d.ts +1 -0
  154. package/dist/core/AiProfileService.test.js +164 -0
  155. package/dist/core/AiProfiles.test.d.ts +1 -0
  156. package/dist/core/AiProfiles.test.js +449 -0
  157. package/dist/core/AttachmentLinkService.d.ts +15 -0
  158. package/dist/core/AttachmentLinkService.js +157 -0
  159. package/dist/core/AuthTokenService.d.ts +44 -0
  160. package/dist/core/AuthTokenService.js +207 -0
  161. package/dist/core/CreatedBy.test.js +134 -6
  162. package/dist/core/DeletedTaskLifecycleService.d.ts +33 -0
  163. package/dist/core/DeletedTaskLifecycleService.js +158 -0
  164. package/dist/core/DeletedTaskTrash.test.d.ts +1 -0
  165. package/dist/core/DeletedTaskTrash.test.js +104 -0
  166. package/dist/core/EntitlementsPolicy.test.js +78 -5
  167. package/dist/core/GlobalSettingsService.d.ts +16 -0
  168. package/dist/core/GlobalSettingsService.js +370 -0
  169. package/dist/core/JsonBackupRuntime.test.d.ts +1 -0
  170. package/dist/core/JsonBackupRuntime.test.js +155 -0
  171. package/dist/core/McpTokenService.d.ts +118 -0
  172. package/dist/core/McpTokenService.js +921 -0
  173. package/dist/core/PlanEntitlementService.d.ts +201 -0
  174. package/dist/core/PlanEntitlementService.js +1442 -0
  175. package/dist/core/PlanVersionPolicy.test.d.ts +1 -0
  176. package/dist/core/PlanVersionPolicy.test.js +178 -0
  177. package/dist/core/PlanningEntities.test.d.ts +1 -0
  178. package/dist/core/PlanningEntities.test.js +95 -0
  179. package/dist/core/ScheduleFields.test.js +15 -19
  180. package/dist/core/SignupMonetizationSettings.test.d.ts +1 -0
  181. package/dist/core/SignupMonetizationSettings.test.js +159 -0
  182. package/dist/core/Stats.test.d.ts +1 -0
  183. package/dist/core/Stats.test.js +36 -0
  184. package/dist/core/SyncReconciliationService.d.ts +93 -0
  185. package/dist/core/SyncReconciliationService.js +406 -0
  186. package/dist/core/SystemAdmin.test.js +578 -13
  187. package/dist/core/TaskActivityService.d.ts +21 -0
  188. package/dist/core/TaskActivityService.js +130 -0
  189. package/dist/core/TaskAttachmentsCanonical.test.d.ts +1 -0
  190. package/dist/core/TaskAttachmentsCanonical.test.js +306 -0
  191. package/dist/core/TaskAuditTimeline.test.d.ts +1 -0
  192. package/dist/core/TaskAuditTimeline.test.js +132 -0
  193. package/dist/core/TaskTaxonomyValidation.test.js +338 -15
  194. package/dist/core/Taskforce.d.ts +930 -183
  195. package/dist/core/Taskforce.ids.test.js +252 -0
  196. package/dist/core/Taskforce.js +3848 -2532
  197. package/dist/core/Taskforce.mcpAuth.test.d.ts +1 -0
  198. package/dist/core/Taskforce.mcpAuth.test.js +343 -0
  199. package/dist/core/Taskforce.realtimeMutation.test.js +57 -2
  200. package/dist/core/TaxonomySettingsService.d.ts +18 -0
  201. package/dist/core/TaxonomySettingsService.js +162 -0
  202. package/dist/core/WorkspaceDelete.test.js +32 -13
  203. package/dist/core/WorkspaceLifecycleService.d.ts +11 -0
  204. package/dist/core/WorkspaceLifecycleService.js +88 -0
  205. package/dist/core/WorkspacePermissions.test.js +95 -0
  206. package/dist/core/WorkspacePlanMode.test.js +114 -1
  207. package/dist/core/WorkspacePreferenceService.d.ts +41 -0
  208. package/dist/core/WorkspacePreferenceService.js +246 -0
  209. package/dist/core/WorkspaceSyncSettings.test.d.ts +1 -0
  210. package/dist/core/WorkspaceSyncSettings.test.js +65 -0
  211. package/dist/core/__tests__/TaskAttachmentsCanonical.test.d.ts +1 -0
  212. package/dist/core/__tests__/TaskAttachmentsCanonical.test.js +212 -0
  213. package/dist/core/shared.d.ts +36 -0
  214. package/dist/core/shared.js +128 -0
  215. package/dist/core/types.d.ts +614 -0
  216. package/dist/core/types.js +27 -0
  217. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +56 -0
  218. package/dist/documentReviews/DocumentReviewCommentStore.js +230 -0
  219. package/dist/documentReviews/DocumentReviewSessionStore.d.ts +52 -0
  220. package/dist/documentReviews/DocumentReviewSessionStore.js +193 -0
  221. package/dist/documentReviews/DocumentReviewSessionStore.test.d.ts +1 -0
  222. package/dist/documentReviews/DocumentReviewSessionStore.test.js +127 -0
  223. package/dist/documentReviews/service.d.ts +68 -0
  224. package/dist/documentReviews/service.js +210 -0
  225. package/dist/documentReviews/types.d.ts +58 -0
  226. package/dist/documentReviews/types.js +1 -0
  227. package/dist/hooks/auth/useAuthGuardPolicy.d.ts +2 -0
  228. package/dist/hooks/auth/useAuthGuardPolicy.js +1 -0
  229. package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +15 -0
  230. package/dist/hooks/tasks/useCurrentTaskRelations.js +37 -0
  231. package/dist/hooks/tasks/useTaskActions.d.ts +3 -0
  232. package/dist/hooks/tasks/useTaskActions.js +2 -0
  233. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +65 -0
  234. package/dist/hooks/tasks/useTaskEditorNavigation.js +235 -0
  235. package/dist/hooks/tasks/useTaskFilters.d.ts +2 -0
  236. package/dist/hooks/tasks/useTaskFilters.js +2 -0
  237. package/dist/hooks/tasks/useTaskFormActions.d.ts +58 -0
  238. package/dist/hooks/tasks/useTaskFormActions.js +365 -0
  239. package/dist/hooks/tasks/useTaskRelationships.d.ts +16 -0
  240. package/dist/hooks/tasks/useTaskRelationships.js +64 -0
  241. package/dist/hooks/ui/useResourceExport.d.ts +19 -0
  242. package/dist/hooks/ui/useResourceExport.js +84 -0
  243. package/dist/hooks/ui/useSettingsModel.d.ts +203 -0
  244. package/dist/hooks/ui/useSettingsModel.js +125 -0
  245. package/dist/hooks/ui/useSettingsPersistence.d.ts +36 -0
  246. package/dist/hooks/ui/useSettingsPersistence.js +254 -0
  247. package/dist/hooks/ui/useSettingsTaxonomyManagement.d.ts +119 -0
  248. package/dist/hooks/ui/useSettingsTaxonomyManagement.js +536 -0
  249. package/dist/hooks/ui/useUiNotice.d.ts +1 -0
  250. package/dist/hooks/ui/useUiNotice.js +1 -0
  251. package/dist/hooks/ui/useWorkflowTemplates.d.ts +37 -0
  252. package/dist/hooks/ui/useWorkflowTemplates.js +111 -0
  253. package/dist/hooks/ui/useZenMode.d.ts +5 -0
  254. package/dist/hooks/ui/useZenMode.js +32 -0
  255. package/dist/hooks/useFilterSort.d.ts +60 -0
  256. package/dist/hooks/useFilterSort.js +362 -0
  257. package/dist/hooks/useFilterSort.test.d.ts +1 -0
  258. package/dist/hooks/useFilterSort.test.js +333 -0
  259. package/dist/hooks/useRealtimeSync.d.ts +1 -0
  260. package/dist/hooks/useRealtimeSync.js +24 -9
  261. package/dist/hooks/useRealtimeSync.test.js +28 -1
  262. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.d.ts +1 -0
  263. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +34 -0
  264. package/dist/hooks/useSyncOrchestrator.d.ts +65 -103
  265. package/dist/hooks/useSyncOrchestrator.js +1538 -670
  266. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +700 -174
  267. package/dist/hooks/useTaskData.d.ts +35 -0
  268. package/dist/hooks/useTaskData.js +239 -0
  269. package/dist/hooks/useTaskData.test.d.ts +1 -0
  270. package/dist/hooks/useTaskData.test.js +119 -0
  271. package/dist/hooks/useTaskMutations.d.ts +46 -0
  272. package/dist/hooks/useTaskMutations.js +472 -0
  273. package/dist/hooks/useTaskMutations.test.d.ts +1 -0
  274. package/dist/hooks/useTaskMutations.test.js +80 -0
  275. package/dist/hooks/useTaskforce.contract.test.d.ts +1 -0
  276. package/dist/hooks/useTaskforce.contract.test.js +7 -0
  277. package/dist/hooks/useTaskforce.d.ts +260 -295
  278. package/dist/hooks/useTaskforce.js +1954 -2623
  279. package/dist/hooks/useTaskforce.priority-filters.test.js +6 -11
  280. package/dist/hooks/useTaskforce.sync-behavior.test.d.ts +1 -0
  281. package/dist/hooks/useTaskforce.sync-behavior.test.js +1120 -0
  282. package/dist/hooks/useUiNotice.d.ts +16 -0
  283. package/dist/hooks/useUiNotice.js +49 -0
  284. package/dist/hooks/useWorkspaceSyncController.d.ts +23 -46
  285. package/dist/hooks/useWorkspaceSyncController.js +280 -461
  286. package/dist/hooks/useWorkspaceSyncController.test.js +106 -199
  287. package/dist/hooks/workspace/useTaskforceApiRouting.d.ts +8 -0
  288. package/dist/hooks/workspace/useTaskforceApiRouting.js +91 -0
  289. package/dist/hooks/workspace/useTaskforceApiRouting.test.d.ts +1 -0
  290. package/dist/hooks/workspace/useTaskforceApiRouting.test.js +60 -0
  291. package/dist/hooks/workspace/useWorkspaceSyncController.d.ts +1 -0
  292. package/dist/hooks/workspace/useWorkspaceSyncController.js +1 -0
  293. package/dist/hooks/workspace/workspaceLocalState.d.ts +30 -0
  294. package/dist/hooks/workspace/workspaceLocalState.js +101 -0
  295. package/dist/localization/locales/en-US.d.ts +1 -8
  296. package/dist/localization/locales/en-US.js +4 -11
  297. package/dist/localization/locales/es-419.js +2 -9
  298. package/dist/localization/locales/pt-BR.js +2 -9
  299. package/dist/localization/localizationCatalogs.test.d.ts +1 -0
  300. package/dist/localization/localizationCatalogs.test.js +37 -0
  301. package/dist/main.d.ts +1 -0
  302. package/dist/main.js +9 -15
  303. package/dist/mcp/clientIntegrations.d.ts +33 -0
  304. package/dist/mcp/clientIntegrations.js +199 -0
  305. package/dist/mcp/clientIntegrations.test.d.ts +1 -0
  306. package/dist/mcp/clientIntegrations.test.js +110 -0
  307. package/dist/mcp/index.d.ts +2 -0
  308. package/dist/mcp/index.js +2 -0
  309. package/dist/mcp/optionResolution.test.js +6 -2
  310. package/dist/mcp/runtime.d.ts +120 -0
  311. package/dist/mcp/runtime.js +5668 -0
  312. package/dist/mcp/runtime.test.d.ts +1 -0
  313. package/dist/mcp/runtime.test.js +3293 -0
  314. package/dist/mcp/server.js +2 -1793
  315. package/dist/mcp/structuredCommentValidation.test.d.ts +1 -0
  316. package/dist/{__tests__ → mcp}/structuredCommentValidation.test.js +1 -1
  317. package/dist/mcp/structuredDocValidation.js +1 -2
  318. package/dist/mcp/structuredDocValidation.test.d.ts +1 -0
  319. package/dist/{__tests__ → mcp}/structuredDocValidation.test.js +9 -4
  320. package/dist/mcp/toolRegistry.d.ts +570 -0
  321. package/dist/mcp/toolRegistry.js +90 -0
  322. package/dist/mcp/toolRegistry.test.d.ts +1 -0
  323. package/dist/mcp/toolRegistry.test.js +30 -0
  324. package/dist/migrations/billingSchemaParity.test.js +111 -0
  325. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  326. package/dist/migrations/taskSchemaMigrations.js +681 -39
  327. package/dist/migrations/taskSchemaMigrations.test.d.ts +1 -0
  328. package/dist/migrations/taskSchemaMigrations.test.js +210 -0
  329. package/dist/plugins/vite.js +13 -7
  330. package/dist/public/apple-touch-icon.png +0 -0
  331. package/dist/public/archive/phoenix/apple-touch-icon.png +0 -0
  332. package/dist/public/archive/phoenix/favicon.ico +0 -0
  333. package/dist/public/archive/phoenix/site.webmanifest +1 -0
  334. package/dist/public/favicon-96x96.png +0 -0
  335. package/dist/public/favicon.ico +0 -0
  336. package/dist/public/favicon.svg +17 -0
  337. package/dist/public/site.webmanifest +21 -1
  338. package/dist/public/web-app-manifest-192x192.png +0 -0
  339. package/dist/public/web-app-manifest-512x512.png +0 -0
  340. package/dist/releaseVersion.test.d.ts +1 -0
  341. package/dist/{__tests__/releaseVersion.test.js → releaseVersion.test.js} +1 -1
  342. package/dist/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
  343. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
  344. package/dist/resources/templates/workflows/collaborate.yaml +11 -5
  345. package/dist/resources/templates/workflows/do.yaml +8 -2
  346. package/dist/resources/templates/workflows/evaluate.yaml +13 -7
  347. package/dist/resources/templates/workflows/execute.yaml +40 -23
  348. package/dist/resources/templates/workflows/plan.yaml +15 -8
  349. package/dist/resources/templates/workflows/review.yaml +14 -8
  350. package/dist/runtime/appGateDefinitions.d.ts +32 -0
  351. package/dist/runtime/appGateDefinitions.js +32 -0
  352. package/dist/runtime/appGates.d.ts +29 -0
  353. package/dist/runtime/appGates.js +53 -0
  354. package/dist/runtime/appGates.test.d.ts +1 -0
  355. package/dist/runtime/appGates.test.js +42 -0
  356. package/dist/runtime/migrationFlags.d.ts +1 -0
  357. package/dist/runtime/migrationFlags.js +1 -0
  358. package/dist/server/annotatedAttachmentsRoutes.test.d.ts +1 -0
  359. package/dist/server/annotatedAttachmentsRoutes.test.js +473 -0
  360. package/dist/server/auth.js +14 -2
  361. package/dist/server/auth.test.js +21 -1
  362. package/dist/server/cors.js +11 -5
  363. package/dist/server/cors.test.js +6 -0
  364. package/dist/server/documentReviewRoutes.test.d.ts +1 -0
  365. package/dist/server/documentReviewRoutes.test.js +157 -0
  366. package/dist/server/index.cookieProxy.test.js +46 -1
  367. package/dist/server/index.d.ts +20 -0
  368. package/dist/server/index.js +168 -41
  369. package/dist/server/index.rateLimit.test.js +6 -0
  370. package/dist/server/index.test.js +133 -2
  371. package/dist/server/mockStripe.d.ts +72 -0
  372. package/dist/server/mockStripe.js +357 -0
  373. package/dist/server/realtimeSyncWs.js +4 -0
  374. package/dist/server/routes/admin.d.ts +114 -0
  375. package/dist/server/routes/admin.js +2226 -0
  376. package/dist/server/routes/annotatedAttachments.d.ts +24 -0
  377. package/dist/server/routes/annotatedAttachments.js +235 -0
  378. package/dist/server/routes/auth.d.ts +61 -0
  379. package/dist/server/routes/auth.js +1296 -0
  380. package/dist/server/{routes.billing.d.ts → routes/billing.d.ts} +3 -2
  381. package/dist/server/routes/billing.js +2001 -0
  382. package/dist/server/routes/billing.test.d.ts +1 -0
  383. package/dist/server/routes/billing.test.js +1631 -0
  384. package/dist/server/routes/documentReviews.d.ts +11 -0
  385. package/dist/server/routes/documentReviews.js +191 -0
  386. package/dist/server/routes/documents.d.ts +118 -0
  387. package/dist/server/routes/documents.js +1113 -0
  388. package/dist/server/routes/resources.d.ts +25 -0
  389. package/dist/server/routes/resources.js +225 -0
  390. package/dist/server/routes/shared.d.ts +35 -0
  391. package/dist/server/routes/shared.js +305 -0
  392. package/dist/server/routes/shared.test.d.ts +1 -0
  393. package/dist/server/routes/shared.test.js +32 -0
  394. package/dist/server/{routes.sync.d.ts → routes/sync.d.ts} +5 -5
  395. package/dist/server/routes/sync.integration.test.d.ts +1 -0
  396. package/dist/server/routes/sync.integration.test.js +2003 -0
  397. package/dist/server/routes/sync.js +3143 -0
  398. package/dist/server/routes/tasks.d.ts +72 -0
  399. package/dist/server/routes/tasks.js +1252 -0
  400. package/dist/server/routes/workspaces.d.ts +32 -0
  401. package/dist/server/routes/workspaces.js +307 -0
  402. package/dist/server/routes.d.ts +8 -9
  403. package/dist/server/routes.js +968 -4092
  404. package/dist/server/routes.test.js +9043 -2415
  405. package/dist/server/runtimeMode.d.ts +1 -1
  406. package/dist/server/runtimeMode.js +3 -18
  407. package/dist/server/runtimeMode.test.js +3 -3
  408. package/dist/server/securityHeaders.d.ts +1 -1
  409. package/dist/server/securityHeaders.js +65 -6
  410. package/dist/server/securityHeaders.test.js +40 -2
  411. package/dist/services/templateEngine.test.d.ts +1 -0
  412. package/dist/{__tests__ → services}/templateEngine.test.js +1 -1
  413. package/dist/services/templates.test.d.ts +1 -0
  414. package/dist/{__tests__ → services}/templates.test.js +1 -1
  415. package/dist/services/workflowDocumentFixtures.test.d.ts +1 -0
  416. package/dist/{__tests__ → services}/workflowDocumentFixtures.test.js +4 -4
  417. package/dist/services/workflowExportMatrix.test.d.ts +1 -0
  418. package/dist/{__tests__ → services}/workflowExportMatrix.test.js +1 -1
  419. package/dist/services/workflowExportSnapshots.test.d.ts +1 -0
  420. package/dist/services/workflowGeneration.test.d.ts +1 -0
  421. package/dist/services/workflowSimulation.test.d.ts +1 -0
  422. package/dist/services/workflowSimulation.test.js +113 -0
  423. package/dist/services/workflowV2Policy.test.d.ts +1 -0
  424. package/dist/{__tests__ → services}/workflowV2Policy.test.js +2 -2
  425. package/dist/shared/aiProfileSurfaceType.d.ts +9 -0
  426. package/dist/shared/aiProfileSurfaceType.js +49 -0
  427. package/dist/shared/customTaxonomyLibrary.d.ts +11 -0
  428. package/dist/shared/customTaxonomyLibrary.js +276 -0
  429. package/dist/shared/customTaxonomyLibrary.test.d.ts +1 -0
  430. package/dist/shared/customTaxonomyLibrary.test.js +20 -0
  431. package/dist/shared/taxonomyCatalog.d.ts +19 -0
  432. package/dist/shared/taxonomyCatalog.js +36 -0
  433. package/dist/shared/taxonomyDefaults.d.ts +29 -0
  434. package/dist/shared/taxonomyDefaults.js +26 -0
  435. package/dist/shared/taxonomyLibrary.d.ts +15 -0
  436. package/dist/shared/taxonomyLibrary.js +98 -0
  437. package/dist/shared/taxonomyLibrary.test.d.ts +1 -0
  438. package/dist/shared/taxonomyLibrary.test.js +26 -0
  439. package/dist/shared/taxonomyState.d.ts +36 -0
  440. package/dist/shared/taxonomyState.js +73 -0
  441. package/dist/shared/taxonomyState.test.d.ts +1 -0
  442. package/dist/shared/taxonomyState.test.js +71 -0
  443. package/dist/shared/workflowDefaults.d.ts +9 -0
  444. package/dist/shared/workflowDefaults.js +11 -0
  445. package/dist/storage/documentIntegrity.d.ts +2 -0
  446. package/dist/storage/documentIntegrity.js +34 -17
  447. package/dist/storage/documentPurge.d.ts +2 -1
  448. package/dist/storage/documentPurge.js +35 -8
  449. package/dist/storage/index.d.ts +4 -0
  450. package/dist/storage/index.js +2 -0
  451. package/dist/storage/objectStorage.d.ts +1 -1
  452. package/dist/storage/objectStorageClient.d.ts +6 -4
  453. package/dist/storage/objectStorageClient.js +77 -29
  454. package/dist/storage/objectStorageClient.test.d.ts +1 -0
  455. package/dist/storage/objectStorageClient.test.js +57 -0
  456. package/dist/storage/objectStorageConfig.js +3 -1
  457. package/dist/storage/objectStorageConfig.test.d.ts +1 -0
  458. package/dist/storage/objectStorageConfig.test.js +38 -0
  459. package/dist/storage/postgresAdapter.d.ts +5 -0
  460. package/dist/storage/postgresAdapter.js +2 -2
  461. package/dist/storage/postgresAdapter.test.d.ts +1 -0
  462. package/dist/storage/postgresAdapter.test.js +29 -0
  463. package/dist/storage/taskAssetStore.d.ts +7 -4
  464. package/dist/storage/taskAssetStore.js +65 -60
  465. package/dist/storage/workspaceAssetStore.d.ts +122 -0
  466. package/dist/storage/workspaceAssetStore.js +496 -0
  467. package/dist/storage/workspaceAssetStore.test.d.ts +1 -0
  468. package/dist/storage/workspaceAssetStore.test.js +501 -0
  469. package/dist/sync/cloudSyncApi.d.ts +33 -2
  470. package/dist/sync/cloudSyncApi.js +37 -15
  471. package/dist/sync/cloudSyncApi.test.js +60 -3
  472. package/dist/sync/index.d.ts +2 -0
  473. package/dist/sync/index.js +3 -0
  474. package/dist/sync/syncService.d.ts +25 -0
  475. package/dist/sync/syncService.js +184 -16
  476. package/dist/sync/syncService.test.js +289 -25
  477. package/dist/sync/workspaceRepair.d.ts +114 -0
  478. package/dist/sync/workspaceRepair.js +566 -0
  479. package/dist/sync/workspaceSyncModel.d.ts +230 -2
  480. package/dist/sync/workspaceSyncModel.js +456 -17
  481. package/dist/sync/workspaceSyncModel.test.js +642 -0
  482. package/dist/sync/workspaceSyncState.d.ts +12 -0
  483. package/dist/sync/workspaceSyncState.js +12 -0
  484. package/dist/sync/workspaceSyncSurface.d.ts +33 -0
  485. package/dist/sync/workspaceSyncSurface.js +74 -0
  486. package/dist/types.d.ts +143 -18
  487. package/dist/types.js +9 -24
  488. package/dist/ui/assets/AgentsModule-TVmCgizS.js +1 -0
  489. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +1 -0
  490. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CAyhnPeR.js +3 -0
  491. package/dist/ui/assets/DocumentWorkspace-BOCw5e4D.js +250 -0
  492. package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +1 -0
  493. package/dist/ui/assets/InitiativesModule-CN0r02Oi.js +1 -0
  494. package/dist/ui/assets/PlansPage-BlVC_lRq.css +1 -0
  495. package/dist/ui/assets/PlansPage-FcQSNLZd.js +1 -0
  496. package/dist/ui/assets/TaskSettings-BwB9NtmJ.css +1 -0
  497. package/dist/ui/assets/TaskSettings-Cw5zYD1L.js +8 -0
  498. package/dist/ui/assets/WorkflowsModule-CY9R2zPB.js +5 -0
  499. package/dist/ui/assets/index-Bzqy5QGm.js +6 -0
  500. package/dist/ui/assets/index-DxRiI3tY.css +1 -0
  501. package/dist/ui/assets/vendor-dnd-DRzYolkg.js +5 -0
  502. package/dist/ui/assets/{vendor-icons-ZFG3SGwo.js → vendor-icons-QZyhEwgT.js} +1 -1
  503. package/dist/ui/assets/{vendor-markdown-CKYkQHfj.js → vendor-markdown-BUxTU7dS.js} +1 -1
  504. package/dist/ui/assets/vendor-react-CKJs5o3c.js +61 -0
  505. package/dist/ui/assets/vendor-router-BbWMxlnO.js +3 -0
  506. package/dist/ui/branding/logos/logo.png +0 -0
  507. package/dist/ui/branding/logos/logo_dark.svg +27 -0
  508. package/dist/ui/branding/logos/logo_favicon.svg +35 -0
  509. package/dist/ui/branding/logos/logo_light.svg +27 -0
  510. package/dist/ui/favicon/apple-touch-icon.png +0 -0
  511. package/dist/ui/favicon/archive/phoenix/apple-touch-icon.png +0 -0
  512. package/dist/ui/favicon/archive/phoenix/favicon.ico +0 -0
  513. package/dist/ui/favicon/archive/phoenix/site.webmanifest +1 -0
  514. package/dist/ui/favicon/favicon-96x96.png +0 -0
  515. package/dist/ui/favicon/favicon.ico +0 -0
  516. package/dist/ui/favicon/favicon.svg +17 -0
  517. package/dist/ui/favicon/site.webmanifest +21 -1
  518. package/dist/ui/favicon/web-app-manifest-192x192.png +0 -0
  519. package/dist/ui/favicon/web-app-manifest-512x512.png +0 -0
  520. package/dist/ui/index.html +10 -7
  521. package/dist/ui/product/screen_01.png +0 -0
  522. package/dist/ui/product/screen_02.png +0 -0
  523. package/dist/ui/product/screen_03.png +0 -0
  524. package/dist/utils/annotatedAttachments.d.ts +20 -0
  525. package/dist/utils/annotatedAttachments.js +74 -0
  526. package/dist/utils/annotatedAttachments.test.d.ts +1 -0
  527. package/dist/utils/annotatedAttachments.test.js +108 -0
  528. package/dist/utils/assignees.d.ts +26 -0
  529. package/dist/utils/assignees.js +132 -0
  530. package/dist/utils/canonicalAssetKind.d.ts +16 -0
  531. package/dist/utils/canonicalAssetKind.js +39 -0
  532. package/dist/utils/canonicalAssetKind.test.d.ts +1 -0
  533. package/dist/utils/canonicalAssetKind.test.js +24 -0
  534. package/dist/utils/coalescedRefresh.d.ts +5 -0
  535. package/dist/utils/coalescedRefresh.js +16 -0
  536. package/dist/utils/coalescedRefresh.test.d.ts +1 -0
  537. package/dist/utils/coalescedRefresh.test.js +30 -0
  538. package/dist/utils/constants.d.ts +16 -3
  539. package/dist/utils/constants.icons.test.js +2 -1
  540. package/dist/utils/constants.js +70 -13
  541. package/dist/utils/contextAssetEvents.d.ts +7 -0
  542. package/dist/utils/contextAssetEvents.js +6 -0
  543. package/dist/utils/contextFiles.d.ts +14 -3
  544. package/dist/utils/contextFiles.js +40 -8
  545. package/dist/utils/documentManagerApi.d.ts +6 -0
  546. package/dist/utils/documentManagerApi.js +19 -0
  547. package/dist/utils/documentNames.d.ts +24 -0
  548. package/dist/utils/documentNames.js +91 -0
  549. package/dist/utils/documentReferences.d.ts +9 -0
  550. package/dist/utils/documentReferences.js +11 -0
  551. package/dist/utils/entityReferences.d.ts +9 -0
  552. package/dist/utils/entityReferences.js +32 -0
  553. package/dist/utils/imageReferences.d.ts +9 -0
  554. package/dist/utils/imageReferences.js +11 -0
  555. package/dist/utils/planParser.d.ts +2 -2
  556. package/dist/utils/planParser.js +11 -11
  557. package/dist/utils/planParser.test.d.ts +1 -0
  558. package/dist/{__tests__ → utils}/planParser.test.js +22 -22
  559. package/dist/utils/planningReferences.d.ts +17 -0
  560. package/dist/utils/planningReferences.js +30 -0
  561. package/dist/utils/planningReferences.test.d.ts +1 -0
  562. package/dist/utils/planningReferences.test.js +17 -0
  563. package/dist/utils/taskActivity.d.ts +9 -0
  564. package/dist/utils/taskActivity.js +147 -0
  565. package/dist/utils/taskActivity.test.d.ts +1 -0
  566. package/dist/utils/taskActivity.test.js +34 -0
  567. package/dist/utils/taskDraftDefaults.d.ts +21 -0
  568. package/dist/utils/taskDraftDefaults.js +40 -0
  569. package/dist/utils/taskDraftDefaults.test.d.ts +1 -0
  570. package/dist/utils/taskDraftDefaults.test.js +34 -0
  571. package/dist/utils/taskNormalization.d.ts +25 -0
  572. package/dist/utils/taskNormalization.js +161 -0
  573. package/dist/utils/taskNormalization.test.d.ts +1 -0
  574. package/dist/utils/taskNormalization.test.js +158 -0
  575. package/dist/utils/taskReferences.d.ts +5 -0
  576. package/dist/utils/taskReferences.js +11 -0
  577. package/dist/utils/taskforceApiClient.d.ts +2 -0
  578. package/dist/utils/taskforceApiClient.js +101 -3
  579. package/dist/utils/taskforceApiClient.test.d.ts +1 -0
  580. package/dist/utils/taskforceApiClient.test.js +44 -0
  581. package/dist/utils/taxonomyFilterOptions.d.ts +2 -0
  582. package/dist/utils/taxonomyFilterOptions.js +17 -0
  583. package/dist/utils/taxonomyFormDefaults.d.ts +3 -0
  584. package/dist/utils/taxonomyFormDefaults.js +28 -0
  585. package/dist/utils/taxonomyFormDefaults.test.d.ts +1 -0
  586. package/dist/utils/taxonomyFormDefaults.test.js +63 -0
  587. package/dist/utils/taxonomyLifecycle.d.ts +3 -0
  588. package/dist/utils/taxonomyLifecycle.js +17 -0
  589. package/dist/utils/taxonomySorting.d.ts +7 -0
  590. package/dist/utils/taxonomySorting.js +74 -0
  591. package/dist/utils/theme.d.ts +15 -0
  592. package/dist/utils/theme.js +23 -0
  593. package/dist/utils/uiNotice.d.ts +7 -0
  594. package/dist/utils/uiNotice.js +6 -0
  595. package/dist/utils/uiNotice.test.d.ts +1 -0
  596. package/dist/utils/uiNotice.test.js +18 -0
  597. package/dist/utils/workspaceIdentity.d.ts +14 -0
  598. package/dist/utils/workspaceIdentity.js +21 -0
  599. package/dist/utils/workspaceIdentity.test.js +30 -1
  600. package/dist/utils/workspaceSyncPresentation.d.ts +20 -0
  601. package/dist/utils/workspaceSyncPresentation.js +21 -0
  602. package/dist/utils/workspaceSyncPresentation.test.d.ts +1 -0
  603. package/dist/utils/workspaceSyncPresentation.test.js +36 -0
  604. package/package.json +28 -23
  605. package/scripts/bootstrap-playwright-auth.mjs +155 -0
  606. package/scripts/check-compat-boundaries.mjs +41 -0
  607. package/scripts/check-env.ts +9 -2
  608. package/scripts/debug-login.mjs +32 -0
  609. package/scripts/migrate-planning-model.ts +233 -0
  610. package/scripts/migrate-task-data-assets.mjs +408 -0
  611. package/scripts/playwright-auth.sh +11 -0
  612. package/scripts/run-dev-proxy.sh +2 -0
  613. package/scripts/update-homebrew-formula.sh +20 -3
  614. package/scripts/with-esbuild.sh +11 -0
  615. package/src/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
  616. package/src/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
  617. package/src/resources/templates/workflows/collaborate.yaml +11 -5
  618. package/src/resources/templates/workflows/do.yaml +8 -2
  619. package/src/resources/templates/workflows/evaluate.yaml +13 -7
  620. package/src/resources/templates/workflows/execute.yaml +40 -23
  621. package/src/resources/templates/workflows/plan.yaml +15 -8
  622. package/src/resources/templates/workflows/review.yaml +14 -8
  623. package/dist/TaskforceScreenshot.d.ts +0 -11
  624. package/dist/TaskforceScreenshot.js +0 -113
  625. package/dist/compat/priorityCompat.d.ts +0 -2
  626. package/dist/compat/priorityCompat.js +0 -24
  627. package/dist/components/features/settings/TaxonomyManager 2.d.ts +0 -52
  628. package/dist/components/features/settings/TaxonomyManager 2.js +0 -75
  629. package/dist/components/task/TaskKanban 2.d.ts +0 -76
  630. package/dist/components/task/TaskKanban 2.js +0 -1004
  631. package/dist/components/task/TaskScreenshotSection.d.ts +0 -15
  632. package/dist/components/task/TaskScreenshotSection.js +0 -22
  633. package/dist/components/views/StandaloneLayout 2.d.ts +0 -8
  634. package/dist/components/views/StandaloneLayout 2.js +0 -1660
  635. package/dist/core/InitiativeTemplates.test.js +0 -50
  636. package/dist/core/ParentLifecycle.test.js +0 -98
  637. package/dist/migrations/clientMigrations.d.ts +0 -9
  638. package/dist/migrations/clientMigrations.js +0 -74
  639. package/dist/migrations/flags.d.ts +0 -6
  640. package/dist/migrations/flags.js +0 -8
  641. package/dist/migrations/taskMigrations.d.ts +0 -71
  642. package/dist/migrations/taskMigrations.js +0 -236
  643. package/dist/migrations/taskMigrations.test.js +0 -34
  644. package/dist/server/routes.billing.js +0 -991
  645. package/dist/server/routes.billing.test.js +0 -387
  646. package/dist/server/routes.sync.integration.test.js +0 -470
  647. package/dist/server/routes.sync.js +0 -1141
  648. package/dist/soak/syncSoakHarness.d.ts +0 -6
  649. package/dist/soak/syncSoakHarness.js +0 -10
  650. package/dist/ui/assets/index-0W5vyCpn.css +0 -1
  651. package/dist/ui/assets/index-MCZuNNfn.js +0 -23
  652. package/dist/ui/assets/logo_white_01-0Vx-iIIv.png +0 -0
  653. package/dist/ui/assets/vendor-dnd-BI1K77C1.js +0 -5
  654. package/dist/ui/assets/vendor-react-DdIDsh7f.js +0 -9
  655. package/dist/ui/assets/vendor-router-BtiNU7Dl.js +0 -3
  656. package/dist/utils/taskHierarchy.d.ts +0 -4
  657. package/dist/utils/taskHierarchy.js +0 -69
  658. package/dist/utils/taskHierarchy.test.js +0 -38
  659. package/dist/utils/taskParenting.d.ts +0 -3
  660. package/dist/utils/taskParenting.js +0 -24
  661. package/dist/utils/taskParenting.test.js +0 -21
  662. package/dist/utils/taskRelations.d.ts +0 -6
  663. package/dist/utils/taskRelations.js +0 -24
  664. package/dist/utils/taskRelations.test.js +0 -34
  665. package/scripts/check-compat-boundaries.js +0 -48
  666. /package/dist/{__tests__/planParser.test.d.ts → TaskforceCore.filter-persistence.test.d.ts} +0 -0
  667. /package/dist/{__tests__/releaseVersion.test.d.ts → TaskforceCore.routing.test.d.ts} +0 -0
  668. /package/dist/{__tests__/structuredCommentValidation.test.d.ts → annotatedAttachments/AnnotatedAttachmentSessionStore.test.d.ts} +0 -0
  669. /package/dist/{__tests__/structuredDocValidation.test.d.ts → annotatedAttachments/payload.test.d.ts} +0 -0
  670. /package/dist/{__tests__/templateEngine.test.d.ts → annotatedAttachments/types.js} +0 -0
  671. /package/dist/{__tests__/templates.test.d.ts → compat/workspaceSyncCompat.test.d.ts} +0 -0
  672. /package/dist/{__tests__/workflowDocumentFixtures.test.d.ts → components/features/AgentsModule.test.d.ts} +0 -0
  673. /package/dist/{__tests__/workflowExportMatrix.test.d.ts → components/features/AnnotatedAttachmentWorkspace.test.d.ts} +0 -0
  674. /package/dist/{__tests__/workflowExportSnapshots.test.d.ts → components/features/DocumentWorkspace.test.d.ts} +0 -0
  675. /package/dist/{__tests__/workflowGeneration.test.d.ts → components/features/settings/TaxonomyLibraryManager.test.d.ts} +0 -0
  676. /package/dist/{__tests__/workflowV2Policy.test.d.ts → components/task/TaskActionHeader.test.d.ts} +0 -0
  677. /package/dist/{core/InitiativeTemplates.test.d.ts → components/task/TaskKanban.planning-drop.test.d.ts} +0 -0
  678. /package/dist/{core/ParentLifecycle.test.d.ts → components/task/TaskStatusActions.test.d.ts} +0 -0
  679. /package/dist/{migrations/taskMigrations.test.d.ts → components/ui/TopNoticeLayer.test.d.ts} +0 -0
  680. /package/dist/{server/routes.billing.test.d.ts → components/views/AppShellHeader.test.d.ts} +0 -0
  681. /package/dist/{server/routes.sync.integration.test.d.ts → components/views/PlanComparisonPage.test.d.ts} +0 -0
  682. /package/dist/{utils/taskHierarchy.test.d.ts → components/views/chrome/WorkspaceChromeSections.test.d.ts} +0 -0
  683. /package/dist/{utils/taskParenting.test.d.ts → components/views/chrome/workspaceChrome.test.d.ts} +0 -0
  684. /package/dist/{utils/taskRelations.test.d.ts → components/views/panels/DocumentFilterToolbar.test.d.ts} +0 -0
  685. /package/dist/public/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
  686. /package/dist/public/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
  687. /package/dist/public/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
  688. /package/dist/public/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
  689. /package/dist/public/{favicon.png → archive/phoenix/favicon.png} +0 -0
  690. /package/dist/{__tests__ → services}/workflowExportSnapshots.test.js +0 -0
  691. /package/dist/{__tests__ → services}/workflowGeneration.test.js +0 -0
  692. /package/dist/ui/favicon/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
  693. /package/dist/ui/favicon/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
  694. /package/dist/ui/favicon/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
  695. /package/dist/ui/favicon/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
  696. /package/dist/ui/favicon/{favicon.png → archive/phoenix/favicon.png} +0 -0
@@ -0,0 +1,207 @@
1
+ import { randomBytes } from 'crypto';
2
+ import { TaskforceRuleError } from './types.js';
3
+ import { hashAuthToken, hashPassword, generateUuidV7 } from './shared.js';
4
+ /**
5
+ * Handles one-time auth token lifecycle (email verification, password reset, invite acceptance)
6
+ * and the thin read/write helpers for email-verification and password state.
7
+ */
8
+ export class AuthTokenService {
9
+ db;
10
+ tenantId;
11
+ constructor(db, tenantId) {
12
+ this.db = db;
13
+ this.tenantId = tenantId;
14
+ }
15
+ generateEntityId(prefix) {
16
+ return `${prefix}-${generateUuidV7()}`;
17
+ }
18
+ // ─── Internal token primitives ────────────────────────────────────────────
19
+ // Not truly private so that Taskforce.ts invite methods can delegate through
20
+ // this service without needing to know the DB schema.
21
+ createOneTimeAuthToken(userId, purpose, ttlSeconds, workspaceId) {
22
+ const normalizedUserId = String(userId || '').trim();
23
+ if (!normalizedUserId) {
24
+ throw new TaskforceRuleError('userId is required', 400, 'USER_ID_REQUIRED');
25
+ }
26
+ const normalizedWorkspaceId = String(workspaceId || '').trim() || null;
27
+ const safeTtl = Math.max(60, Math.floor(Number(ttlSeconds) || 0));
28
+ const now = new Date();
29
+ const expiresAt = new Date(now.getTime() + safeTtl * 1000).toISOString();
30
+ const token = randomBytes(24).toString('hex');
31
+ const tokenHash = hashAuthToken(token);
32
+ const tokenId = this.generateEntityId(`auth-${purpose}`);
33
+ // Keep previously issued tokens valid until they are consumed or expired.
34
+ // This avoids accidental invalidation when users request a resend and click an older email link.
35
+ this.db.prepare(`
36
+ DELETE FROM auth_tokens
37
+ WHERE tenant_id = ? AND user_id = ? AND purpose = ? AND (used_at IS NOT NULL OR expires_at < ?)
38
+ `).run(this.tenantId, normalizedUserId, purpose, now.toISOString());
39
+ this.db.prepare(`
40
+ INSERT INTO auth_tokens (id, tenant_id, user_id, workspace_id, purpose, token_hash, expires_at, used_at, revoked_at, created_at)
41
+ VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, ?)
42
+ `).run(tokenId, this.tenantId, normalizedUserId, normalizedWorkspaceId, purpose, tokenHash, expiresAt, now.toISOString());
43
+ return token;
44
+ }
45
+ consumeOneTimeAuthToken(token, purpose) {
46
+ const normalized = String(token || '').trim();
47
+ if (!normalized)
48
+ return null;
49
+ const tokenHash = hashAuthToken(normalized);
50
+ const now = new Date().toISOString();
51
+ const row = this.db.prepare(`
52
+ SELECT id, user_id, workspace_id, expires_at, used_at, revoked_at
53
+ FROM auth_tokens
54
+ WHERE tenant_id = ? AND purpose = ? AND token_hash = ?
55
+ LIMIT 1
56
+ `).get(this.tenantId, purpose, tokenHash);
57
+ if (!row?.id || !row.user_id || row.used_at || row.revoked_at)
58
+ return null;
59
+ if (!row.expires_at || row.expires_at < now)
60
+ return null;
61
+ this.db.prepare(`
62
+ UPDATE auth_tokens
63
+ SET used_at = ?
64
+ WHERE tenant_id = ? AND id = ?
65
+ `).run(now, this.tenantId, row.id);
66
+ return {
67
+ userId: row.user_id,
68
+ workspaceId: row.workspace_id ? String(row.workspace_id) : undefined
69
+ };
70
+ }
71
+ inspectOneTimeAuthToken(token, purpose) {
72
+ const normalized = String(token || '').trim();
73
+ if (!normalized)
74
+ return { state: 'missing' };
75
+ const tokenHash = hashAuthToken(normalized);
76
+ const now = new Date().toISOString();
77
+ const row = this.db.prepare(`
78
+ SELECT user_id, workspace_id, expires_at, used_at, revoked_at
79
+ FROM auth_tokens
80
+ WHERE tenant_id = ? AND purpose = ? AND token_hash = ?
81
+ LIMIT 1
82
+ `).get(this.tenantId, purpose, tokenHash);
83
+ if (!row?.user_id)
84
+ return { state: 'missing' };
85
+ const workspaceId = row.workspace_id ? String(row.workspace_id) : undefined;
86
+ if (row.revoked_at)
87
+ return { state: 'revoked', userId: row.user_id, workspaceId };
88
+ if (row.used_at)
89
+ return { state: 'used', userId: row.user_id, workspaceId };
90
+ if (!row.expires_at || row.expires_at < now)
91
+ return { state: 'expired', userId: row.user_id, workspaceId };
92
+ return { state: 'valid', userId: row.user_id, workspaceId };
93
+ }
94
+ // ─── Public methods ───────────────────────────────────────────────────────
95
+ isEmailVerified(email) {
96
+ const normalizedEmail = String(email || '').trim().toLowerCase();
97
+ if (!normalizedEmail)
98
+ return false;
99
+ const row = this.db.prepare(`
100
+ SELECT email_verified_at
101
+ FROM users
102
+ WHERE tenant_id = ? AND email = ?
103
+ LIMIT 1
104
+ `).get(this.tenantId, normalizedEmail);
105
+ return Boolean(row?.email_verified_at);
106
+ }
107
+ markEmailVerified(email) {
108
+ const normalizedEmail = String(email || '').trim().toLowerCase();
109
+ if (!normalizedEmail || !normalizedEmail.includes('@'))
110
+ return false;
111
+ const now = new Date().toISOString();
112
+ const result = this.db.prepare(`
113
+ UPDATE users
114
+ SET email_verified_at = COALESCE(email_verified_at, ?), updated_at = ?
115
+ WHERE tenant_id = ? AND email = ?
116
+ `).run(now, now, this.tenantId, normalizedEmail);
117
+ const changed = Number(result?.changes || 0);
118
+ return changed > 0;
119
+ }
120
+ requestEmailVerification(input) {
121
+ const normalizedEmail = String(input.email || '').trim().toLowerCase();
122
+ if (!normalizedEmail || !normalizedEmail.includes('@')) {
123
+ throw new TaskforceRuleError('Valid email is required', 400, 'EMAIL_REQUIRED');
124
+ }
125
+ const row = this.db.prepare(`
126
+ SELECT id, email_verified_at
127
+ FROM users
128
+ WHERE tenant_id = ? AND email = ?
129
+ LIMIT 1
130
+ `).get(this.tenantId, normalizedEmail);
131
+ if (!row?.id || row.email_verified_at)
132
+ return {};
133
+ const token = this.createOneTimeAuthToken(row.id, 'email_verification', input.ttlSeconds || 60 * 60 * 24);
134
+ return { token };
135
+ }
136
+ verifyEmailWithToken(token) {
137
+ const consumed = this.consumeOneTimeAuthToken(token, 'email_verification');
138
+ if (!consumed?.userId)
139
+ return false;
140
+ const now = new Date().toISOString();
141
+ this.db.prepare(`
142
+ UPDATE users
143
+ SET email_verified_at = ?, updated_at = ?
144
+ WHERE tenant_id = ? AND id = ?
145
+ `).run(now, now, this.tenantId, consumed.userId);
146
+ return true;
147
+ }
148
+ requestPasswordReset(input) {
149
+ const normalizedEmail = String(input.email || '').trim().toLowerCase();
150
+ if (!normalizedEmail || !normalizedEmail.includes('@')) {
151
+ throw new TaskforceRuleError('Valid email is required', 400, 'EMAIL_REQUIRED');
152
+ }
153
+ const row = this.db.prepare(`
154
+ SELECT id
155
+ FROM users
156
+ WHERE tenant_id = ? AND email = ?
157
+ LIMIT 1
158
+ `).get(this.tenantId, normalizedEmail);
159
+ if (!row?.id)
160
+ return {};
161
+ const token = this.createOneTimeAuthToken(row.id, 'password_reset', input.ttlSeconds || 60 * 60);
162
+ return { token };
163
+ }
164
+ requestInviteAcceptance(input) {
165
+ const userId = String(input.userId || '').trim();
166
+ const workspaceId = String(input.workspaceId || '').trim();
167
+ if (!userId) {
168
+ throw new TaskforceRuleError('userId is required', 400, 'USER_ID_REQUIRED');
169
+ }
170
+ if (!workspaceId) {
171
+ throw new TaskforceRuleError('workspaceId is required', 400, 'WORKSPACE_ID_REQUIRED');
172
+ }
173
+ const user = this.db.prepare(`
174
+ SELECT id FROM users WHERE tenant_id = ? AND id = ? LIMIT 1
175
+ `).get(this.tenantId, userId);
176
+ if (!user?.id) {
177
+ throw new TaskforceRuleError('User not found', 404, 'USER_NOT_FOUND');
178
+ }
179
+ const membership = this.db.prepare(`
180
+ SELECT workspace_id
181
+ FROM workspace_memberships
182
+ WHERE tenant_id = ? AND user_id = ? AND workspace_id = ?
183
+ LIMIT 1
184
+ `).get(this.tenantId, userId, workspaceId);
185
+ if (!membership?.workspace_id) {
186
+ throw new TaskforceRuleError('Workspace membership not found', 404, 'WORKSPACE_MEMBERSHIP_NOT_FOUND');
187
+ }
188
+ const token = this.createOneTimeAuthToken(userId, 'invite_accept', input.ttlSeconds || 60 * 60 * 24 * 7, workspaceId);
189
+ return { token };
190
+ }
191
+ resetPasswordWithToken(input) {
192
+ const password = String(input.password || '');
193
+ if (!password || password.length < 8) {
194
+ throw new TaskforceRuleError('Password must be at least 8 characters', 400, 'PASSWORD_TOO_SHORT');
195
+ }
196
+ const consumed = this.consumeOneTimeAuthToken(input.token, 'password_reset');
197
+ if (!consumed?.userId)
198
+ return false;
199
+ const now = new Date().toISOString();
200
+ this.db.prepare(`
201
+ UPDATE users
202
+ SET password_hash = ?, auth_provider = ?, is_disabled = 0, updated_at = ?
203
+ WHERE tenant_id = ? AND id = ?
204
+ `).run(hashPassword(password), 'password', now, this.tenantId, consumed.userId);
205
+ return true;
206
+ }
207
+ }
@@ -18,7 +18,7 @@ afterEach(() => {
18
18
  }
19
19
  });
20
20
  describe('TaskforceCore - createdBy Field', () => {
21
- it('populates createdBy field correctly on creation', () => {
21
+ it('does not persist new generic AI createdBy values on creation', () => {
22
22
  const projectRoot = createProjectRoot();
23
23
  createdRoots.push(projectRoot);
24
24
  const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
@@ -26,7 +26,25 @@ describe('TaskforceCore - createdBy Field', () => {
26
26
  title: 'AI Task',
27
27
  createdBy: 'AI Agent'
28
28
  });
29
- expect(task.createdBy).toBe('AI Agent');
29
+ expect(task.createdBy).toBeUndefined();
30
+ });
31
+ it('preserves legacy generic AI createdBy values when hydrating stored tasks', () => {
32
+ const projectRoot = createProjectRoot();
33
+ createdRoots.push(projectRoot);
34
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
35
+ const task = core.createTask({ title: 'Legacy AI task' });
36
+ core.db.prepare(`
37
+ UPDATE tasks
38
+ SET created_by = ?
39
+ WHERE tenant_id = ? AND workspace_id = ? AND id = ?
40
+ `).run('agent', 'default', 'default', task.id);
41
+ const hydrated = core.getTask(task.id);
42
+ expect(hydrated?.createdBy).toBe('agent');
43
+ expect(hydrated?.createdByActor).toEqual(expect.objectContaining({
44
+ id: 'agent',
45
+ kind: 'ai',
46
+ isNamed: false
47
+ }));
30
48
  });
31
49
  it('defaults createdBy to undefined if not provided', () => {
32
50
  const projectRoot = createProjectRoot();
@@ -35,7 +53,7 @@ describe('TaskforceCore - createdBy Field', () => {
35
53
  const task = core.createTask({ title: 'User Task' });
36
54
  expect(task.createdBy).toBeUndefined();
37
55
  });
38
- it('infers assignee user from [User] title hint when assignee is missing', () => {
56
+ it('treats legacy [User] title hints as unassigned when assignee is missing', () => {
39
57
  const projectRoot = createProjectRoot();
40
58
  createdRoots.push(projectRoot);
41
59
  const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
@@ -43,9 +61,9 @@ describe('TaskforceCore - createdBy Field', () => {
43
61
  title: '[User] Configure backups',
44
62
  createdBy: 'AI Agent'
45
63
  });
46
- expect(task.assignee).toBe('user');
64
+ expect(task.assignee).toBe('unassigned');
47
65
  });
48
- it('overrides unassigned with explicit owner hint for compatibility', () => {
66
+ it('keeps legacy owner hints unassigned for compatibility', () => {
49
67
  const projectRoot = createProjectRoot();
50
68
  createdRoots.push(projectRoot);
51
69
  const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
@@ -55,6 +73,116 @@ describe('TaskforceCore - createdBy Field', () => {
55
73
  assignee: 'unassigned',
56
74
  createdBy: 'AI Agent'
57
75
  });
58
- expect(task.assignee).toBe('user');
76
+ expect(task.assignee).toBe('unassigned');
77
+ });
78
+ it('defaults AI-authored tasks to unassigned when no explicit assignee is provided', () => {
79
+ const projectRoot = createProjectRoot();
80
+ createdRoots.push(projectRoot);
81
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
82
+ const task = core.createTask({
83
+ title: 'AI-created task',
84
+ createdBy: 'AI Agent'
85
+ });
86
+ expect(task.assignee).toBe('unassigned');
87
+ });
88
+ it('repairs unknown member assignees to unassigned', () => {
89
+ const projectRoot = createProjectRoot();
90
+ createdRoots.push(projectRoot);
91
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
92
+ const task = core.createTask({
93
+ title: 'Assign to workspace member',
94
+ assignee: 'member-123',
95
+ createdBy: 'AI Agent'
96
+ });
97
+ expect(task.assignee).toBe('unassigned');
98
+ });
99
+ it('normalizes legacy agent assignees to unassigned on create', () => {
100
+ const projectRoot = createProjectRoot();
101
+ createdRoots.push(projectRoot);
102
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
103
+ const task = core.createTask({
104
+ title: 'Legacy AI-owned task',
105
+ assignee: 'agent',
106
+ createdBy: 'AI Agent'
107
+ });
108
+ expect(task.assignee).toBe('unassigned');
109
+ });
110
+ it('preserves registered AI profile assignees', () => {
111
+ const projectRoot = createProjectRoot();
112
+ createdRoots.push(projectRoot);
113
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
114
+ core.createWorkspace({ workspaceId: 'workspace-1', name: 'Workspace 1' });
115
+ const { profile } = core.resolveAiProfile({
116
+ workspaceId: 'workspace-1',
117
+ name: 'Codex'
118
+ });
119
+ const task = core.createTask({
120
+ title: 'Assign to Codex',
121
+ assignee: profile.id
122
+ }, { workspaceId: 'workspace-1' });
123
+ expect(task.assignee).toBe(profile.id);
124
+ });
125
+ it('self-repairs stored assignees that no longer exist back to unassigned', () => {
126
+ const projectRoot = createProjectRoot();
127
+ createdRoots.push(projectRoot);
128
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
129
+ core.createWorkspace({ workspaceId: 'workspace-1', name: 'Workspace 1' });
130
+ const { profile } = core.resolveAiProfile({
131
+ workspaceId: 'workspace-1',
132
+ name: 'Codex'
133
+ });
134
+ const task = core.createTask({
135
+ title: 'Task with stale assignee',
136
+ assignee: profile.id
137
+ }, { workspaceId: 'workspace-1' });
138
+ core.db.prepare(`
139
+ UPDATE tasks
140
+ SET assignee = ?
141
+ WHERE tenant_id = ? AND workspace_id = ? AND id = ?
142
+ `).run('ghost-assignee', 'default', 'workspace-1', task.id);
143
+ const repaired = core.getTask(task.id, 'workspace-1');
144
+ expect(repaired?.assignee).toBe('unassigned');
145
+ const persisted = core.db.prepare(`
146
+ SELECT assignee
147
+ FROM tasks
148
+ WHERE tenant_id = ? AND workspace_id = ? AND id = ?
149
+ `).get('default', 'workspace-1', task.id);
150
+ expect(persisted?.assignee).toBe('unassigned');
151
+ });
152
+ it('normalizes escaped newlines for AI-authored task descriptions on create', () => {
153
+ const projectRoot = createProjectRoot();
154
+ createdRoots.push(projectRoot);
155
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
156
+ const task = core.createTask({
157
+ title: 'AI task with escaped description',
158
+ description: 'Phase 1\\n\\nPhase 2',
159
+ createdBy: 'AI Agent'
160
+ });
161
+ expect(task.description).toBe('Phase 1\n\nPhase 2');
162
+ });
163
+ it('preserves literal escaped newlines for manual task descriptions on create', () => {
164
+ const projectRoot = createProjectRoot();
165
+ createdRoots.push(projectRoot);
166
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
167
+ const task = core.createTask({
168
+ title: 'Manual task with literal backslashes',
169
+ description: 'Keep literal \\n\\n text'
170
+ });
171
+ expect(task.description).toBe('Keep literal \\n\\n text');
172
+ });
173
+ it('normalizes escaped newlines when updating an AI-authored task description', () => {
174
+ const projectRoot = createProjectRoot();
175
+ createdRoots.push(projectRoot);
176
+ const core = new TaskforceCore({ projectRoot, storagePath: '.taskforce' });
177
+ const task = core.createTask({
178
+ title: 'AI task to update',
179
+ createdBy: 'AI Agent'
180
+ });
181
+ const updated = core.updateTask(task.id, {
182
+ description: 'Line 1\\r\\n\\r\\nLine 2',
183
+ createdBy: 'AI Agent'
184
+ });
185
+ expect(updated?.description).toBe('Line 1\n\nLine 2');
186
+ expect(updated?.createdBy).toBeUndefined();
59
187
  });
60
188
  });
@@ -0,0 +1,33 @@
1
+ import type { DatabaseAdapter } from '../storage/databaseAdapter.js';
2
+ import type { DeletedTaskDetails, DeletedTaskRecord, DeletedTaskSource, TaskActor, TaskItem } from './Taskforce.js';
3
+ export interface DeletedTaskLifecycleServiceDeps {
4
+ db: DatabaseAdapter;
5
+ tenantId: string;
6
+ createRuleError: (message: string, statusCode?: number, code?: string) => Error;
7
+ generateEntityId: (prefix: string) => string;
8
+ normalizeWorkspaceId: (workspaceId: string | undefined) => string;
9
+ resolveWorkspaceActor: (workspaceId: string, actorRef: unknown) => TaskActor | null;
10
+ sanitizeOrderInDay: (value: unknown) => number | null;
11
+ sanitizeDateOnly: (value: unknown) => string | null;
12
+ normalizeTaskEventActor: (actorRef: unknown, workspaceId: string) => {
13
+ actor: string;
14
+ actorType: 'human' | 'ai' | 'system';
15
+ actorProfile: TaskActor | null;
16
+ };
17
+ }
18
+ export declare function normalizeTaskSnapshotForRestoreService(deps: DeletedTaskLifecycleServiceDeps, task: TaskItem): TaskItem;
19
+ export declare function mapDeletedTaskRowService(deps: DeletedTaskLifecycleServiceDeps, row: Record<string, unknown>): DeletedTaskRecord | null;
20
+ export declare function pruneDeletedTasksService(deps: DeletedTaskLifecycleServiceDeps, workspaceId?: string, nowIso?: string): number;
21
+ export declare function purgeExpiredDeletedTasksService(deps: DeletedTaskLifecycleServiceDeps, workspaceId?: string, retentionDays?: number): number;
22
+ export declare function addDeletedTaskRecordService(deps: DeletedTaskLifecycleServiceDeps, input: {
23
+ task: TaskItem;
24
+ workspaceId: string;
25
+ actor: unknown;
26
+ source?: DeletedTaskSource;
27
+ details?: DeletedTaskDetails;
28
+ deletedAt?: string;
29
+ }): DeletedTaskRecord;
30
+ export declare function listDeletedTasksService(deps: DeletedTaskLifecycleServiceDeps, workspaceId?: string): {
31
+ deleted: DeletedTaskRecord[];
32
+ };
33
+ export declare function getDeletedTaskService(deps: DeletedTaskLifecycleServiceDeps, id: string, workspaceId?: string): DeletedTaskRecord | null;
@@ -0,0 +1,158 @@
1
+ const DELETED_TASK_RETENTION_MS = 90 * 24 * 60 * 60 * 1000;
2
+ function normalizeDeletedTaskDetails(details) {
3
+ if (!details || typeof details !== 'object' || Array.isArray(details))
4
+ return {};
5
+ return details;
6
+ }
7
+ export function normalizeTaskSnapshotForRestoreService(deps, task) {
8
+ return {
9
+ ...task,
10
+ comments: Array.isArray(task.comments) ? task.comments : [],
11
+ taskEvents: Array.isArray(task.taskEvents) ? task.taskEvents : [],
12
+ activity: Array.isArray(task.activity) ? task.activity : [],
13
+ attachments: Array.isArray(task.attachments) ? task.attachments : [],
14
+ orderInDay: deps.sanitizeOrderInDay(task.orderInDay),
15
+ scheduledDate: deps.sanitizeDateOnly(task.scheduledDate),
16
+ dueDate: deps.sanitizeDateOnly(task.dueDate)
17
+ };
18
+ }
19
+ export function mapDeletedTaskRowService(deps, row) {
20
+ const workspaceId = deps.normalizeWorkspaceId(typeof row.workspace_id === 'string' ? row.workspace_id : undefined);
21
+ const actor = String(row.actor || 'system').trim() || 'system';
22
+ const source = String(row.source || 'system').trim();
23
+ let details = {};
24
+ let taskSnapshot = null;
25
+ try {
26
+ details = row.details_json ? JSON.parse(String(row.details_json)) : {};
27
+ }
28
+ catch {
29
+ details = {};
30
+ }
31
+ try {
32
+ const parsed = row.task_snapshot_json ? JSON.parse(String(row.task_snapshot_json)) : null;
33
+ taskSnapshot = parsed && typeof parsed === 'object'
34
+ ? normalizeTaskSnapshotForRestoreService(deps, parsed)
35
+ : null;
36
+ }
37
+ catch {
38
+ taskSnapshot = null;
39
+ }
40
+ if (!taskSnapshot)
41
+ return null;
42
+ return {
43
+ id: String(row.id || '').trim(),
44
+ taskId: String(row.task_id || '').trim(),
45
+ workspaceId,
46
+ deletedAt: String(row.deleted_at || '').trim(),
47
+ actor,
48
+ actorType: row.actor_type === 'ai' || row.actor_type === 'human' || row.actor_type === 'system'
49
+ ? row.actor_type
50
+ : 'system',
51
+ source: source === 'ui' || source === 'mcp' || source === 'sync' || source === 'workspace-delete' ? source : 'system',
52
+ details,
53
+ taskSnapshot,
54
+ actorProfile: actor === 'system' ? null : deps.resolveWorkspaceActor(workspaceId, actor)
55
+ };
56
+ }
57
+ export function pruneDeletedTasksService(deps, workspaceId, nowIso) {
58
+ const cutoff = new Date((nowIso ? Date.parse(nowIso) : Date.now()) - DELETED_TASK_RETENTION_MS).toISOString();
59
+ if (workspaceId) {
60
+ const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);
61
+ const result = deps.db.prepare(`
62
+ DELETE FROM deleted_tasks
63
+ WHERE tenant_id = ?
64
+ AND workspace_id = ?
65
+ AND deleted_at < ?
66
+ `).run(deps.tenantId, normalizedWorkspaceId, cutoff);
67
+ return Number(result?.changes || 0);
68
+ }
69
+ const result = deps.db.prepare(`
70
+ DELETE FROM deleted_tasks
71
+ WHERE tenant_id = ?
72
+ AND deleted_at < ?
73
+ `).run(deps.tenantId, cutoff);
74
+ return Number(result?.changes || 0);
75
+ }
76
+ export function purgeExpiredDeletedTasksService(deps, workspaceId, retentionDays = 90) {
77
+ const cutoff = new Date(Date.now() - (retentionDays * 24 * 60 * 60 * 1000)).toISOString();
78
+ if (typeof workspaceId === 'string' && workspaceId.trim().length > 0) {
79
+ const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);
80
+ const result = deps.db.prepare(`
81
+ DELETE FROM deleted_tasks
82
+ WHERE tenant_id = ?
83
+ AND workspace_id = ?
84
+ AND deleted_at < ?
85
+ `).run(deps.tenantId, normalizedWorkspaceId, cutoff);
86
+ return Number(result?.changes || 0);
87
+ }
88
+ const result = deps.db.prepare(`
89
+ DELETE FROM deleted_tasks
90
+ WHERE tenant_id = ?
91
+ AND deleted_at < ?
92
+ `).run(deps.tenantId, cutoff);
93
+ return Number(result?.changes || 0);
94
+ }
95
+ export function addDeletedTaskRecordService(deps, input) {
96
+ const workspaceId = deps.normalizeWorkspaceId(input.workspaceId);
97
+ const task = normalizeTaskSnapshotForRestoreService(deps, input.task);
98
+ const deletedAt = String(input.deletedAt || '').trim() || new Date().toISOString();
99
+ const { actor, actorType } = deps.normalizeTaskEventActor(input.actor, workspaceId);
100
+ const recordId = deps.generateEntityId('deleted-task');
101
+ const details = normalizeDeletedTaskDetails(input.details);
102
+ deps.db.prepare(`
103
+ INSERT INTO deleted_tasks (
104
+ id, tenant_id, workspace_id, task_id, deleted_at, actor, actor_type, source, details_json, task_snapshot_json
105
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
106
+ ON CONFLICT (tenant_id, workspace_id, task_id) DO UPDATE SET
107
+ deleted_at = excluded.deleted_at,
108
+ actor = excluded.actor,
109
+ actor_type = excluded.actor_type,
110
+ source = excluded.source,
111
+ details_json = excluded.details_json,
112
+ task_snapshot_json = excluded.task_snapshot_json
113
+ `).run(recordId, deps.tenantId, workspaceId, task.id, deletedAt, actor, actorType, input.source || 'system', JSON.stringify(details), JSON.stringify(task));
114
+ const stored = deps.db.prepare(`
115
+ SELECT *
116
+ FROM deleted_tasks
117
+ WHERE tenant_id = ? AND workspace_id = ? AND task_id = ?
118
+ LIMIT 1
119
+ `).get(deps.tenantId, workspaceId, task.id);
120
+ const mapped = stored ? mapDeletedTaskRowService(deps, stored) : null;
121
+ if (!mapped) {
122
+ throw deps.createRuleError('Failed to persist deleted task history', 500, 'DELETED_TASK_PERSIST_FAILED');
123
+ }
124
+ return mapped;
125
+ }
126
+ export function listDeletedTasksService(deps, workspaceId) {
127
+ const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);
128
+ purgeExpiredDeletedTasksService(deps, normalizedWorkspaceId);
129
+ const rows = deps.db.prepare(`
130
+ SELECT *
131
+ FROM deleted_tasks
132
+ WHERE tenant_id = ?
133
+ AND workspace_id = ?
134
+ ORDER BY deleted_at DESC, id DESC
135
+ `).all(deps.tenantId, normalizedWorkspaceId);
136
+ return {
137
+ deleted: rows
138
+ .map((row) => mapDeletedTaskRowService(deps, row))
139
+ .filter((row) => Boolean(row))
140
+ };
141
+ }
142
+ export function getDeletedTaskService(deps, id, workspaceId) {
143
+ const normalizedWorkspaceId = deps.normalizeWorkspaceId(workspaceId);
144
+ const normalizedId = String(id || '').trim();
145
+ if (!normalizedId)
146
+ return null;
147
+ purgeExpiredDeletedTasksService(deps, normalizedWorkspaceId);
148
+ const row = deps.db.prepare(`
149
+ SELECT *
150
+ FROM deleted_tasks
151
+ WHERE tenant_id = ?
152
+ AND workspace_id = ?
153
+ AND (id = ? OR task_id = ?)
154
+ ORDER BY deleted_at DESC, id DESC
155
+ LIMIT 1
156
+ `).get(deps.tenantId, normalizedWorkspaceId, normalizedId, normalizedId);
157
+ return row ? mapDeletedTaskRowService(deps, row) : null;
158
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,104 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
5
+ import { TaskforceCore } from './Taskforce';
6
+ function makeCore() {
7
+ const projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'taskforce-deleted-'));
8
+ const core = new TaskforceCore({
9
+ projectRoot,
10
+ storagePath: path.join(projectRoot, '.taskforce')
11
+ });
12
+ return {
13
+ core,
14
+ cleanup: () => {
15
+ core.close();
16
+ fs.rmSync(projectRoot, { recursive: true, force: true });
17
+ }
18
+ };
19
+ }
20
+ describe('TaskforceCore deleted task lifecycle', () => {
21
+ it('moves deleted tasks into deleted-task history with actor, source, and snapshot data', () => {
22
+ const { core, cleanup } = makeCore();
23
+ try {
24
+ const task = core.createTask({
25
+ title: 'Trash me',
26
+ description: 'Forensics matter',
27
+ createdBy: 'user'
28
+ }, { workspaceId: 'workspace-a', actorRef: 'user' });
29
+ const deleted = core.softDeleteTask(task.id, 'workspace-a', { actorRef: 'user', source: 'ui' });
30
+ expect(deleted).toEqual(expect.objectContaining({
31
+ taskId: task.id,
32
+ source: 'ui',
33
+ actor: 'user',
34
+ actorType: 'human',
35
+ taskSnapshot: expect.objectContaining({
36
+ id: task.id,
37
+ title: 'Trash me',
38
+ description: 'Forensics matter'
39
+ })
40
+ }));
41
+ expect(core.getTask(task.id, 'workspace-a')).toBeNull();
42
+ expect(core.listDeletedTasks('workspace-a').deleted).toHaveLength(1);
43
+ }
44
+ finally {
45
+ cleanup();
46
+ }
47
+ });
48
+ it('restores a deleted task back into active tasks and removes it from deleted-task history', () => {
49
+ const { core, cleanup } = makeCore();
50
+ try {
51
+ const task = core.createTask({
52
+ title: 'Bring me back',
53
+ comments: [{ id: 'comment-1', author: 'user', text: 'Keep this note', timestamp: '2026-03-22T10:00:00.000Z' }],
54
+ createdBy: 'user'
55
+ }, { workspaceId: 'workspace-a', actorRef: 'user' });
56
+ const deleted = core.softDeleteTask(task.id, 'workspace-a', { actorRef: 'user', source: 'ui' });
57
+ const restored = core.restoreDeletedTask(deleted.id, 'workspace-a', { actorRef: 'user' });
58
+ expect(restored).toEqual(expect.objectContaining({
59
+ id: task.id,
60
+ title: 'Bring me back',
61
+ comments: expect.arrayContaining([
62
+ expect.objectContaining({ text: 'Keep this note' })
63
+ ])
64
+ }));
65
+ expect(core.listDeletedTasks('workspace-a').deleted).toHaveLength(0);
66
+ expect(core.getTask(task.id, 'workspace-a')).not.toBeNull();
67
+ expect(core.listTaskEvents(task.id, 'workspace-a').map((event) => event.action)).toContain('task-restored');
68
+ }
69
+ finally {
70
+ cleanup();
71
+ }
72
+ });
73
+ it('purges deleted task records older than the retention window', () => {
74
+ const { core, cleanup } = makeCore();
75
+ try {
76
+ const staleTask = core.createTask({
77
+ title: 'Old deleted task',
78
+ createdBy: 'user'
79
+ }, { workspaceId: 'workspace-a', actorRef: 'user' });
80
+ const freshTask = core.createTask({
81
+ title: 'Fresh deleted task',
82
+ createdBy: 'user'
83
+ }, { workspaceId: 'workspace-a', actorRef: 'user' });
84
+ const staleDeleted = core.softDeleteTask(staleTask.id, 'workspace-a', { actorRef: 'user', source: 'ui' });
85
+ const freshDeleted = core.softDeleteTask(freshTask.id, 'workspace-a', { actorRef: 'user', source: 'ui' });
86
+ const staleDeletedAt = new Date(Date.now() - (91 * 24 * 60 * 60 * 1000)).toISOString();
87
+ core.db.prepare(`
88
+ UPDATE deleted_tasks
89
+ SET deleted_at = ?
90
+ WHERE tenant_id = ? AND workspace_id = ? AND task_id = ?
91
+ `).run(staleDeletedAt, core.getTenantId(), 'workspace-a', staleTask.id);
92
+ const listed = core.listDeletedTasks('workspace-a').deleted;
93
+ expect(listed).toHaveLength(1);
94
+ expect(listed[0]?.taskId).toBe(freshTask.id);
95
+ expect(core.getDeletedTask(staleDeleted.id, 'workspace-a')).toBeNull();
96
+ expect(core.getDeletedTask(freshDeleted.id, 'workspace-a')).toEqual(expect.objectContaining({
97
+ taskId: freshTask.id
98
+ }));
99
+ }
100
+ finally {
101
+ cleanup();
102
+ }
103
+ });
104
+ });