@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
@@ -1,3 +1,22 @@
1
+ function hasTable(db, tableName) {
2
+ if (db.provider === 'postgres') {
3
+ const row = db.prepare(`
4
+ SELECT tablename AS name
5
+ FROM pg_catalog.pg_tables
6
+ WHERE schemaname = current_schema()
7
+ AND tablename = ?
8
+ LIMIT 1
9
+ `).get(tableName);
10
+ return Boolean(String(row?.name || '').trim());
11
+ }
12
+ const row = db.prepare(`
13
+ SELECT name
14
+ FROM sqlite_master
15
+ WHERE type = 'table' AND name = ?
16
+ LIMIT 1
17
+ `).get(tableName);
18
+ return Boolean(String(row?.name || '').trim());
19
+ }
1
20
  export function ensureTenantSchema(db) {
2
21
  const taskColumns = db.prepare(`PRAGMA table_info(tasks)`).all();
3
22
  const hasTaskTenantColumn = taskColumns.some((c) => c.name === 'tenant_id');
@@ -9,16 +28,10 @@ export function ensureTenantSchema(db) {
9
28
  if (!hasCommentTenantColumn) {
10
29
  db.exec(`ALTER TABLE comments ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
11
30
  }
12
- const screenshotColumns = db.prepare(`PRAGMA table_info(screenshots)`).all();
13
- const hasScreenshotTenantColumn = screenshotColumns.some((c) => c.name === 'tenant_id');
14
- if (!hasScreenshotTenantColumn) {
15
- db.exec(`ALTER TABLE screenshots ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
16
- }
17
31
  db.exec(`
18
32
  CREATE INDEX IF NOT EXISTS idx_tasks_tenant ON tasks(tenant_id);
19
33
  CREATE INDEX IF NOT EXISTS idx_tasks_tenant_archived ON tasks(tenant_id, is_archived);
20
34
  CREATE INDEX IF NOT EXISTS idx_comments_tenant_task ON comments(tenant_id, task_id);
21
- CREATE INDEX IF NOT EXISTS idx_screenshots_tenant_task ON screenshots(tenant_id, task_id);
22
35
  `);
23
36
  }
24
37
  export function ensureParentTaskSchema(db) {
@@ -106,6 +119,74 @@ export function ensureAssigneeTaskSchema(db) {
106
119
  }
107
120
  db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee)`);
108
121
  }
122
+ export function ensureTaskReferenceSchema(db) {
123
+ const columns = db.prepare(`PRAGMA table_info(tasks)`).all();
124
+ const hasReferenceNumberColumn = columns.some((c) => c.name === 'reference_number');
125
+ if (!hasReferenceNumberColumn) {
126
+ db.exec(`ALTER TABLE tasks ADD COLUMN reference_number INTEGER`);
127
+ }
128
+ db.exec(`
129
+ CREATE TABLE IF NOT EXISTS workspace_task_reference_sequences (
130
+ tenant_id TEXT NOT NULL DEFAULT 'default',
131
+ workspace_id TEXT NOT NULL DEFAULT 'default',
132
+ next_reference_number INTEGER NOT NULL DEFAULT 0,
133
+ PRIMARY KEY (tenant_id, workspace_id)
134
+ );
135
+ `);
136
+ const workspaceRows = db.prepare(`
137
+ SELECT DISTINCT
138
+ COALESCE(tenant_id, 'default') AS tenant_id,
139
+ COALESCE(workspace_id, 'default') AS workspace_id
140
+ FROM tasks
141
+ ORDER BY tenant_id ASC, workspace_id ASC
142
+ `).all();
143
+ const selectRows = db.prepare(`
144
+ SELECT id, reference_number, created_at
145
+ FROM tasks
146
+ WHERE tenant_id = ? AND workspace_id = ?
147
+ ORDER BY created_at ASC, id ASC
148
+ `);
149
+ const updateReference = db.prepare(`
150
+ UPDATE tasks
151
+ SET reference_number = ?
152
+ WHERE tenant_id = ? AND workspace_id = ? AND id = ?
153
+ `);
154
+ const upsertSequence = db.prepare(`
155
+ INSERT INTO workspace_task_reference_sequences (tenant_id, workspace_id, next_reference_number)
156
+ VALUES (?, ?, ?)
157
+ ON CONFLICT (tenant_id, workspace_id) DO UPDATE SET
158
+ next_reference_number = EXCLUDED.next_reference_number
159
+ `);
160
+ for (const workspaceRow of workspaceRows) {
161
+ const tenantId = String(workspaceRow.tenant_id || 'default').trim() || 'default';
162
+ const workspaceId = String(workspaceRow.workspace_id || 'default').trim() || 'default';
163
+ const taskRows = selectRows.all(tenantId, workspaceId);
164
+ const seen = new Set();
165
+ let nextReferenceNumber = 0;
166
+ for (const row of taskRows) {
167
+ const taskId = String(row.id || '').trim();
168
+ if (!taskId)
169
+ continue;
170
+ const rawReferenceNumber = Number(row.reference_number);
171
+ const currentReferenceNumber = Number.isFinite(rawReferenceNumber) && rawReferenceNumber > 0
172
+ ? Math.floor(rawReferenceNumber)
173
+ : null;
174
+ if (currentReferenceNumber && !seen.has(currentReferenceNumber)) {
175
+ seen.add(currentReferenceNumber);
176
+ nextReferenceNumber = Math.max(nextReferenceNumber, currentReferenceNumber);
177
+ continue;
178
+ }
179
+ nextReferenceNumber += 1;
180
+ seen.add(nextReferenceNumber);
181
+ updateReference.run(nextReferenceNumber, tenantId, workspaceId, taskId);
182
+ }
183
+ upsertSequence.run(tenantId, workspaceId, nextReferenceNumber);
184
+ }
185
+ db.exec(`
186
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_workspace_reference
187
+ ON tasks(tenant_id, workspace_id, reference_number);
188
+ `);
189
+ }
109
190
  export function ensureWorkspaceSchema(db) {
110
191
  db.exec(`
111
192
  CREATE TABLE IF NOT EXISTS workspaces (
@@ -162,6 +243,29 @@ export function ensureWorkspaceSchema(db) {
162
243
  FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
163
244
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
164
245
  );
246
+
247
+ CREATE TABLE IF NOT EXISTS mcp_access_tokens (
248
+ id TEXT PRIMARY KEY,
249
+ tenant_id TEXT NOT NULL DEFAULT 'default',
250
+ workspace_id TEXT NOT NULL,
251
+ user_id TEXT NOT NULL,
252
+ name TEXT NOT NULL,
253
+ scopes_json TEXT NOT NULL,
254
+ token_prefix TEXT NOT NULL,
255
+ token_hash TEXT NOT NULL,
256
+ status TEXT NOT NULL DEFAULT 'active',
257
+ last_used_at TEXT,
258
+ last_used_ip TEXT,
259
+ last_used_user_agent TEXT,
260
+ created_by_ip TEXT,
261
+ expires_at TEXT,
262
+ revoked_at TEXT,
263
+ revoked_by_user_id TEXT,
264
+ created_at TEXT NOT NULL,
265
+ updated_at TEXT NOT NULL,
266
+ FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
267
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
268
+ );
165
269
  `);
166
270
  const taskColumns = db.prepare(`PRAGMA table_info(tasks)`).all();
167
271
  const hasTaskWorkspaceColumn = taskColumns.some((c) => c.name === 'workspace_id');
@@ -173,36 +277,75 @@ export function ensureWorkspaceSchema(db) {
173
277
  if (!hasCommentWorkspaceColumn) {
174
278
  db.exec(`ALTER TABLE comments ADD COLUMN workspace_id TEXT NOT NULL DEFAULT 'default'`);
175
279
  }
176
- const screenshotColumns = db.prepare(`PRAGMA table_info(screenshots)`).all();
177
- const hasScreenshotWorkspaceColumn = screenshotColumns.some((c) => c.name === 'workspace_id');
178
- if (!hasScreenshotWorkspaceColumn) {
179
- db.exec(`ALTER TABLE screenshots ADD COLUMN workspace_id TEXT NOT NULL DEFAULT 'default'`);
180
- }
181
- const userColumns = db.prepare(`PRAGMA table_info(users)`).all();
182
- const hasPasswordHashColumn = userColumns.some((c) => c.name === 'password_hash');
183
- if (!hasPasswordHashColumn) {
184
- db.exec(`ALTER TABLE users ADD COLUMN password_hash TEXT`);
185
- }
186
- const hasEmailVerifiedAtColumn = userColumns.some((c) => c.name === 'email_verified_at');
187
- if (!hasEmailVerifiedAtColumn) {
188
- db.exec(`ALTER TABLE users ADD COLUMN email_verified_at TEXT`);
189
- }
190
- const hasSystemRoleColumn = userColumns.some((c) => c.name === 'system_role');
191
- if (!hasSystemRoleColumn) {
192
- db.exec(`ALTER TABLE users ADD COLUMN system_role TEXT NOT NULL DEFAULT 'user'`);
280
+ if (db.provider === 'postgres') {
281
+ const postgresUserRepairs = [
282
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS display_name TEXT`,
283
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_url TEXT`,
284
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS auth_provider TEXT`,
285
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS external_auth_id TEXT`,
286
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS password_hash TEXT`,
287
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS email_verified_at TEXT`,
288
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS beta_access BOOLEAN NOT NULL DEFAULT TRUE`,
289
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS is_disabled BOOLEAN NOT NULL DEFAULT FALSE`,
290
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS updated_at TEXT`,
291
+ `ALTER TABLE users ADD COLUMN IF NOT EXISTS system_role TEXT NOT NULL DEFAULT 'user'`
292
+ ];
293
+ for (const ddl of postgresUserRepairs) {
294
+ try {
295
+ db.exec(ddl);
296
+ }
297
+ catch {
298
+ // Best-effort repair for older deployments.
299
+ }
300
+ }
301
+ const postgresMembershipRepairs = [
302
+ `ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS permission_mode TEXT NOT NULL DEFAULT 'read-write'`,
303
+ `ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS beta_access BOOLEAN NOT NULL DEFAULT TRUE`,
304
+ `ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'active'`,
305
+ `ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS updated_at TEXT`
306
+ ];
307
+ for (const ddl of postgresMembershipRepairs) {
308
+ try {
309
+ db.exec(ddl);
310
+ }
311
+ catch {
312
+ // Best-effort repair for older deployments.
313
+ }
314
+ }
193
315
  }
194
- const hasUserBetaAccessColumn = userColumns.some((c) => c.name === 'beta_access');
195
- if (!hasUserBetaAccessColumn) {
196
- db.exec(`ALTER TABLE users ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE`);
197
- }
198
- const membershipColumns = db.prepare(`PRAGMA table_info(workspace_memberships)`).all();
199
- const hasBetaAccessColumn = membershipColumns.some((c) => c.name === 'beta_access');
200
- const hasPermissionModeColumn = membershipColumns.some((c) => c.name === 'permission_mode');
201
- if (!hasBetaAccessColumn) {
202
- db.exec(`ALTER TABLE workspace_memberships ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE`);
203
- }
204
- if (!hasPermissionModeColumn) {
205
- db.exec(`ALTER TABLE workspace_memberships ADD COLUMN permission_mode TEXT NOT NULL DEFAULT 'read-write'`);
316
+ else {
317
+ const userColumns = db.prepare(`PRAGMA table_info(users)`).all();
318
+ const existingUserColumns = new Set(userColumns.map((column) => String(column.name || '').trim()));
319
+ const sqliteUserRepairs = [
320
+ { name: 'display_name', sql: `ALTER TABLE users ADD COLUMN display_name TEXT` },
321
+ { name: 'avatar_url', sql: `ALTER TABLE users ADD COLUMN avatar_url TEXT` },
322
+ { name: 'auth_provider', sql: `ALTER TABLE users ADD COLUMN auth_provider TEXT` },
323
+ { name: 'external_auth_id', sql: `ALTER TABLE users ADD COLUMN external_auth_id TEXT` },
324
+ { name: 'password_hash', sql: `ALTER TABLE users ADD COLUMN password_hash TEXT` },
325
+ { name: 'email_verified_at', sql: `ALTER TABLE users ADD COLUMN email_verified_at TEXT` },
326
+ { name: 'beta_access', sql: `ALTER TABLE users ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE` },
327
+ { name: 'is_disabled', sql: `ALTER TABLE users ADD COLUMN is_disabled BOOLEAN NOT NULL DEFAULT FALSE` },
328
+ { name: 'updated_at', sql: `ALTER TABLE users ADD COLUMN updated_at TEXT` },
329
+ { name: 'system_role', sql: `ALTER TABLE users ADD COLUMN system_role TEXT NOT NULL DEFAULT 'user'` }
330
+ ];
331
+ for (const column of sqliteUserRepairs) {
332
+ if (!existingUserColumns.has(column.name)) {
333
+ db.exec(column.sql);
334
+ }
335
+ }
336
+ const membershipColumns = db.prepare(`PRAGMA table_info(workspace_memberships)`).all();
337
+ const existingMembershipColumns = new Set(membershipColumns.map((column) => String(column.name || '').trim()));
338
+ const sqliteMembershipRepairs = [
339
+ { name: 'permission_mode', sql: `ALTER TABLE workspace_memberships ADD COLUMN permission_mode TEXT NOT NULL DEFAULT 'read-write'` },
340
+ { name: 'beta_access', sql: `ALTER TABLE workspace_memberships ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE` },
341
+ { name: 'status', sql: `ALTER TABLE workspace_memberships ADD COLUMN status TEXT NOT NULL DEFAULT 'active'` },
342
+ { name: 'updated_at', sql: `ALTER TABLE workspace_memberships ADD COLUMN updated_at TEXT` }
343
+ ];
344
+ for (const column of sqliteMembershipRepairs) {
345
+ if (!existingMembershipColumns.has(column.name)) {
346
+ db.exec(column.sql);
347
+ }
348
+ }
206
349
  }
207
350
  const authTokenColumns = db.prepare(`PRAGMA table_info(auth_tokens)`).all();
208
351
  const hasRevokedAtColumn = authTokenColumns.some((c) => c.name === 'revoked_at');
@@ -213,6 +356,32 @@ export function ensureWorkspaceSchema(db) {
213
356
  if (!hasWorkspaceIdColumn) {
214
357
  db.exec(`ALTER TABLE auth_tokens ADD COLUMN workspace_id TEXT`);
215
358
  }
359
+ const mcpTokenColumns = db.prepare(`PRAGMA table_info(mcp_access_tokens)`).all();
360
+ if (mcpTokenColumns.length > 0) {
361
+ const requiredColumns = [
362
+ { name: 'workspace_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN workspace_id TEXT NOT NULL DEFAULT 'default'` },
363
+ { name: 'user_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN user_id TEXT NOT NULL DEFAULT ''` },
364
+ { name: 'name', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN name TEXT NOT NULL DEFAULT ''` },
365
+ { name: 'scopes_json', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN scopes_json TEXT NOT NULL DEFAULT '[]'` },
366
+ { name: 'token_prefix', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN token_prefix TEXT NOT NULL DEFAULT ''` },
367
+ { name: 'token_hash', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN token_hash TEXT NOT NULL DEFAULT ''` },
368
+ { name: 'status', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN status TEXT NOT NULL DEFAULT 'active'` },
369
+ { name: 'last_used_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_at TEXT` },
370
+ { name: 'last_used_ip', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_ip TEXT` },
371
+ { name: 'last_used_user_agent', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_user_agent TEXT` },
372
+ { name: 'created_by_ip', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN created_by_ip TEXT` },
373
+ { name: 'expires_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN expires_at TEXT` },
374
+ { name: 'revoked_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN revoked_at TEXT` },
375
+ { name: 'revoked_by_user_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN revoked_by_user_id TEXT` },
376
+ { name: 'created_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN created_at TEXT NOT NULL DEFAULT ''` },
377
+ { name: 'updated_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN updated_at TEXT NOT NULL DEFAULT ''` },
378
+ ];
379
+ for (const column of requiredColumns) {
380
+ if (!mcpTokenColumns.some((c) => c.name === column.name)) {
381
+ db.exec(column.sql);
382
+ }
383
+ }
384
+ }
216
385
  db.exec(`
217
386
  CREATE UNIQUE INDEX IF NOT EXISTS idx_workspaces_tenant_slug ON workspaces(tenant_id, slug);
218
387
  CREATE UNIQUE INDEX IF NOT EXISTS idx_users_tenant_email ON users(tenant_id, email);
@@ -223,12 +392,15 @@ export function ensureWorkspaceSchema(db) {
223
392
  CREATE INDEX IF NOT EXISTS idx_tasks_workspace ON tasks(workspace_id);
224
393
  CREATE INDEX IF NOT EXISTS idx_tasks_tenant_workspace_archived ON tasks(tenant_id, workspace_id, is_archived);
225
394
  CREATE INDEX IF NOT EXISTS idx_comments_workspace_task ON comments(workspace_id, task_id);
226
- CREATE INDEX IF NOT EXISTS idx_screenshots_workspace_task ON screenshots(workspace_id, task_id);
227
395
  CREATE INDEX IF NOT EXISTS idx_workspace_memberships_user ON workspace_memberships(user_id);
228
396
  CREATE INDEX IF NOT EXISTS idx_workspace_memberships_workspace ON workspace_memberships(workspace_id);
229
397
  CREATE INDEX IF NOT EXISTS idx_auth_tokens_user_purpose ON auth_tokens(user_id, purpose);
230
398
  CREATE INDEX IF NOT EXISTS idx_auth_tokens_workspace_purpose ON auth_tokens(workspace_id, purpose);
231
399
  CREATE INDEX IF NOT EXISTS idx_auth_tokens_expires ON auth_tokens(expires_at);
400
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_mcp_access_tokens_prefix ON mcp_access_tokens(token_prefix);
401
+ CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_workspace_user ON mcp_access_tokens(workspace_id, user_id);
402
+ CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_status ON mcp_access_tokens(status);
403
+ CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_expires ON mcp_access_tokens(expires_at);
232
404
  `);
233
405
  }
234
406
  export function ensureBillingSchema(db) {
@@ -240,9 +412,9 @@ export function ensureBillingSchema(db) {
240
412
  stripe_subscription_id TEXT,
241
413
  stripe_price_id TEXT,
242
414
  stripe_status TEXT,
243
- tier TEXT NOT NULL DEFAULT 'free',
415
+ tier TEXT NOT NULL DEFAULT '',
244
416
  billing_interval TEXT,
245
- entitlement_state TEXT NOT NULL DEFAULT 'free',
417
+ entitlement_state TEXT NOT NULL DEFAULT 'active',
246
418
  trial_end TEXT,
247
419
  current_period_end TEXT,
248
420
  effective_until TEXT,
@@ -281,10 +453,13 @@ export function ensureBillingSchema(db) {
281
453
  plan_version_id TEXT NOT NULL,
282
454
  billing_interval TEXT NOT NULL,
283
455
  stripe_price_id TEXT NOT NULL,
456
+ pricing_type TEXT NOT NULL DEFAULT 'stripe',
284
457
  active BOOLEAN NOT NULL DEFAULT TRUE,
458
+ unit_amount INTEGER,
459
+ currency TEXT,
285
460
  created_at TEXT NOT NULL,
286
461
  updated_at TEXT NOT NULL,
287
- PRIMARY KEY (tenant_id, stripe_price_id)
462
+ PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id)
288
463
  );
289
464
 
290
465
  CREATE INDEX IF NOT EXISTS idx_user_billing_tenant ON user_billing(tenant_id);
@@ -296,6 +471,159 @@ export function ensureBillingSchema(db) {
296
471
  CREATE INDEX IF NOT EXISTS idx_billing_price_mappings_plan ON billing_price_mappings(tenant_id, plan_version_id);
297
472
  CREATE INDEX IF NOT EXISTS idx_billing_price_mappings_active ON billing_price_mappings(tenant_id, active);
298
473
  `);
474
+ const columns = db.prepare(`PRAGMA table_info(billing_price_mappings)`).all();
475
+ const hasUnitAmountColumn = columns.some((c) => c.name === 'unit_amount');
476
+ const hasCurrencyColumn = columns.some((c) => c.name === 'currency');
477
+ const hasPricingTypeColumn = columns.some((c) => c.name === 'pricing_type');
478
+ if (!hasUnitAmountColumn) {
479
+ db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN unit_amount INTEGER`);
480
+ }
481
+ if (!hasCurrencyColumn) {
482
+ db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN currency TEXT`);
483
+ }
484
+ if (!hasPricingTypeColumn) {
485
+ db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN pricing_type TEXT NOT NULL DEFAULT 'stripe'`);
486
+ }
487
+ ensureBillingPriceMappingsConstraints(db);
488
+ normalizeUserBillingDefaults(db);
489
+ }
490
+ function ensureBillingPriceMappingsConstraints(db) {
491
+ if (db.provider === 'postgres') {
492
+ db.exec(`
493
+ ALTER TABLE billing_price_mappings DROP CONSTRAINT IF EXISTS billing_price_mappings_pkey;
494
+ ALTER TABLE billing_price_mappings
495
+ ADD CONSTRAINT billing_price_mappings_pkey
496
+ PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id);
497
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_billing_price_mappings_active_interval
498
+ ON billing_price_mappings(tenant_id, plan_version_id, billing_interval)
499
+ WHERE active = TRUE;
500
+ `);
501
+ return;
502
+ }
503
+ const indexes = db.prepare(`PRAGMA index_list(billing_price_mappings)`).all();
504
+ const tableInfo = db.prepare(`PRAGMA table_info(billing_price_mappings)`).all();
505
+ const hasActiveIntervalIndex = indexes.some((index) => index.name === 'idx_billing_price_mappings_active_interval');
506
+ const primaryKeyColumns = tableInfo
507
+ .filter((column) => Number(column.pk || 0) > 0)
508
+ .sort((a, b) => Number(a.pk || 0) - Number(b.pk || 0))
509
+ .map((column) => String(column.name || ''));
510
+ const needsPrimaryKeyRepair = primaryKeyColumns.join('|') !== 'tenant_id|plan_version_id|billing_interval|stripe_price_id';
511
+ if (needsPrimaryKeyRepair) {
512
+ db.exec(`
513
+ ALTER TABLE billing_price_mappings RENAME TO billing_price_mappings_legacy;
514
+
515
+ CREATE TABLE billing_price_mappings (
516
+ tenant_id TEXT NOT NULL DEFAULT 'default',
517
+ plan_version_id TEXT NOT NULL,
518
+ billing_interval TEXT NOT NULL,
519
+ stripe_price_id TEXT NOT NULL,
520
+ pricing_type TEXT NOT NULL DEFAULT 'stripe',
521
+ active BOOLEAN NOT NULL DEFAULT TRUE,
522
+ unit_amount INTEGER,
523
+ currency TEXT,
524
+ created_at TEXT NOT NULL,
525
+ updated_at TEXT NOT NULL,
526
+ PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id)
527
+ );
528
+
529
+ INSERT INTO billing_price_mappings (
530
+ tenant_id, plan_version_id, billing_interval, stripe_price_id, pricing_type, active, unit_amount, currency, created_at, updated_at
531
+ )
532
+ SELECT
533
+ tenant_id, plan_version_id, billing_interval, stripe_price_id, COALESCE(pricing_type, 'stripe'), active, unit_amount, currency, created_at, updated_at
534
+ FROM billing_price_mappings_legacy;
535
+
536
+ DROP TABLE billing_price_mappings_legacy;
537
+ `);
538
+ }
539
+ if (!hasActiveIntervalIndex) {
540
+ db.exec(`
541
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_billing_price_mappings_active_interval
542
+ ON billing_price_mappings(tenant_id, plan_version_id, billing_interval)
543
+ WHERE active = 1;
544
+ `);
545
+ }
546
+ }
547
+ function normalizeUserBillingDefaults(db) {
548
+ if (db.provider === 'postgres') {
549
+ db.exec(`
550
+ ALTER TABLE user_billing ALTER COLUMN tier SET DEFAULT '';
551
+ ALTER TABLE user_billing ALTER COLUMN entitlement_state SET DEFAULT 'active';
552
+ `);
553
+ return;
554
+ }
555
+ const columns = db.prepare(`PRAGMA table_info(user_billing)`).all();
556
+ const tierColumn = columns.find((column) => column.name === 'tier');
557
+ const stateColumn = columns.find((column) => column.name === 'entitlement_state');
558
+ const tierDefault = String(tierColumn?.dflt_value ?? '').trim();
559
+ const stateDefault = String(stateColumn?.dflt_value ?? '').trim().toLowerCase();
560
+ const tierNeedsRepair = tierDefault !== "''";
561
+ const stateNeedsRepair = stateDefault !== "'active'";
562
+ if (!tierNeedsRepair && !stateNeedsRepair) {
563
+ return;
564
+ }
565
+ const tx = db.transaction(() => {
566
+ db.exec(`
567
+ ALTER TABLE user_billing RENAME TO user_billing_legacy;
568
+
569
+ CREATE TABLE user_billing (
570
+ user_id TEXT PRIMARY KEY,
571
+ tenant_id TEXT NOT NULL DEFAULT 'default',
572
+ stripe_customer_id TEXT UNIQUE,
573
+ stripe_subscription_id TEXT,
574
+ stripe_price_id TEXT,
575
+ stripe_status TEXT,
576
+ tier TEXT NOT NULL DEFAULT '',
577
+ billing_interval TEXT,
578
+ entitlement_state TEXT NOT NULL DEFAULT 'active',
579
+ trial_end TEXT,
580
+ current_period_end TEXT,
581
+ effective_until TEXT,
582
+ created_at TEXT NOT NULL,
583
+ updated_at TEXT NOT NULL,
584
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
585
+ );
586
+
587
+ INSERT INTO user_billing (
588
+ user_id,
589
+ tenant_id,
590
+ stripe_customer_id,
591
+ stripe_subscription_id,
592
+ stripe_price_id,
593
+ stripe_status,
594
+ tier,
595
+ billing_interval,
596
+ entitlement_state,
597
+ trial_end,
598
+ current_period_end,
599
+ effective_until,
600
+ created_at,
601
+ updated_at
602
+ )
603
+ SELECT
604
+ user_id,
605
+ tenant_id,
606
+ stripe_customer_id,
607
+ stripe_subscription_id,
608
+ stripe_price_id,
609
+ stripe_status,
610
+ tier,
611
+ billing_interval,
612
+ entitlement_state,
613
+ trial_end,
614
+ current_period_end,
615
+ effective_until,
616
+ created_at,
617
+ updated_at
618
+ FROM user_billing_legacy;
619
+
620
+ DROP TABLE user_billing_legacy;
621
+
622
+ CREATE INDEX IF NOT EXISTS idx_user_billing_tenant ON user_billing(tenant_id);
623
+ CREATE INDEX IF NOT EXISTS idx_user_billing_customer ON user_billing(stripe_customer_id);
624
+ `);
625
+ });
626
+ tx();
299
627
  }
300
628
  export function ensureEntitlementsSchema(db) {
301
629
  db.exec(`
@@ -416,6 +744,152 @@ export function ensureTaskAssetsSchema(db) {
416
744
  db.exec(`ALTER TABLE task_assets ADD COLUMN quarantine_status TEXT NOT NULL DEFAULT 'none'`);
417
745
  }
418
746
  }
747
+ export function ensureWorkspaceAssetsSchema(db) {
748
+ db.exec(`
749
+ CREATE TABLE IF NOT EXISTS workspace_assets (
750
+ asset_id TEXT PRIMARY KEY,
751
+ tenant_id TEXT NOT NULL DEFAULT 'default',
752
+ workspace_id TEXT NOT NULL,
753
+ kind TEXT NOT NULL,
754
+ logical_name TEXT,
755
+ original_filename TEXT NOT NULL,
756
+ mime_type TEXT NOT NULL,
757
+ storage_provider TEXT NOT NULL,
758
+ storage_key TEXT NOT NULL,
759
+ content_sha256 TEXT NOT NULL,
760
+ size_bytes INTEGER NOT NULL,
761
+ document_id TEXT,
762
+ version INTEGER,
763
+ is_latest INTEGER NOT NULL DEFAULT 1,
764
+ scan_status TEXT NOT NULL DEFAULT 'clean',
765
+ scan_engine TEXT,
766
+ scan_details TEXT,
767
+ created_by_user_id TEXT,
768
+ created_at TEXT NOT NULL,
769
+ updated_at TEXT NOT NULL,
770
+ deleted_at TEXT,
771
+ purge_after TEXT
772
+ );
773
+
774
+ CREATE INDEX IF NOT EXISTS idx_workspace_assets_workspace_deleted_updated
775
+ ON workspace_assets(tenant_id, workspace_id, deleted_at, updated_at);
776
+ CREATE INDEX IF NOT EXISTS idx_workspace_assets_workspace_kind_updated
777
+ ON workspace_assets(tenant_id, workspace_id, kind, updated_at);
778
+ CREATE INDEX IF NOT EXISTS idx_workspace_assets_document_version
779
+ ON workspace_assets(tenant_id, workspace_id, document_id, version);
780
+ CREATE INDEX IF NOT EXISTS idx_workspace_assets_sha
781
+ ON workspace_assets(tenant_id, workspace_id, content_sha256);
782
+ CREATE INDEX IF NOT EXISTS idx_workspace_assets_purge_after
783
+ ON workspace_assets(purge_after);
784
+
785
+ CREATE TABLE IF NOT EXISTS workspace_asset_links (
786
+ tenant_id TEXT NOT NULL DEFAULT 'default',
787
+ workspace_id TEXT NOT NULL,
788
+ asset_id TEXT NOT NULL,
789
+ task_id TEXT NOT NULL,
790
+ role TEXT NOT NULL,
791
+ display_name TEXT,
792
+ sort_order INTEGER,
793
+ created_at TEXT NOT NULL,
794
+ updated_at TEXT NOT NULL,
795
+ deleted_at TEXT,
796
+ PRIMARY KEY (tenant_id, workspace_id, asset_id, task_id, role)
797
+ );
798
+
799
+ CREATE INDEX IF NOT EXISTS idx_workspace_asset_links_task
800
+ ON workspace_asset_links(tenant_id, workspace_id, task_id, deleted_at, updated_at);
801
+ CREATE INDEX IF NOT EXISTS idx_workspace_asset_links_asset
802
+ ON workspace_asset_links(tenant_id, workspace_id, asset_id, deleted_at, updated_at);
803
+ `);
804
+ const linkColumns = db.prepare(`PRAGMA table_info(workspace_asset_links)`).all();
805
+ const hasDisplayNameColumn = linkColumns.some((c) => c.name === 'display_name');
806
+ if (!hasDisplayNameColumn) {
807
+ db.exec(`ALTER TABLE workspace_asset_links ADD COLUMN display_name TEXT`);
808
+ }
809
+ }
810
+ export function ensureDocumentReferenceSchema(db) {
811
+ const columns = db.prepare(`PRAGMA table_info(workspace_assets)`).all();
812
+ const hasReferenceNumberColumn = columns.some((c) => c.name === 'reference_number');
813
+ if (!hasReferenceNumberColumn) {
814
+ db.exec(`ALTER TABLE workspace_assets ADD COLUMN reference_number INTEGER`);
815
+ }
816
+ // Drop the original cross-kind unique index before backfilling per-kind
817
+ // references. Otherwise existing D-### rows can block image backfills such
818
+ // as I-1 / I-2 while the old uniqueness rule is still active.
819
+ db.exec(`DROP INDEX IF EXISTS idx_workspace_assets_workspace_reference`);
820
+ db.exec(`
821
+ CREATE TABLE IF NOT EXISTS workspace_document_reference_sequences (
822
+ tenant_id TEXT NOT NULL DEFAULT 'default',
823
+ workspace_id TEXT NOT NULL DEFAULT 'default',
824
+ next_reference_number INTEGER NOT NULL DEFAULT 0,
825
+ PRIMARY KEY (tenant_id, workspace_id)
826
+ );
827
+ CREATE TABLE IF NOT EXISTS workspace_image_reference_sequences (
828
+ tenant_id TEXT NOT NULL DEFAULT 'default',
829
+ workspace_id TEXT NOT NULL DEFAULT 'default',
830
+ next_reference_number INTEGER NOT NULL DEFAULT 0,
831
+ PRIMARY KEY (tenant_id, workspace_id)
832
+ );
833
+ `);
834
+ const backfillKindReferences = (kind, sequenceTable) => {
835
+ const workspaceRows = db.prepare(`
836
+ SELECT DISTINCT
837
+ COALESCE(tenant_id, 'default') AS tenant_id,
838
+ COALESCE(workspace_id, 'default') AS workspace_id
839
+ FROM workspace_assets
840
+ WHERE kind = ?
841
+ ORDER BY tenant_id ASC, workspace_id ASC
842
+ `).all(kind);
843
+ const selectRows = db.prepare(`
844
+ SELECT asset_id, reference_number, created_at
845
+ FROM workspace_assets
846
+ WHERE tenant_id = ? AND workspace_id = ? AND kind = ?
847
+ ORDER BY created_at ASC, asset_id ASC
848
+ `);
849
+ const updateReference = db.prepare(`
850
+ UPDATE workspace_assets
851
+ SET reference_number = ?
852
+ WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ?
853
+ `);
854
+ const upsertSequence = db.prepare(`
855
+ INSERT INTO ${sequenceTable} (tenant_id, workspace_id, next_reference_number)
856
+ VALUES (?, ?, ?)
857
+ ON CONFLICT (tenant_id, workspace_id) DO UPDATE SET
858
+ next_reference_number = EXCLUDED.next_reference_number
859
+ `);
860
+ for (const workspaceRow of workspaceRows) {
861
+ const tenantId = String(workspaceRow.tenant_id || 'default').trim() || 'default';
862
+ const workspaceId = String(workspaceRow.workspace_id || 'default').trim() || 'default';
863
+ const assetRows = selectRows.all(tenantId, workspaceId, kind);
864
+ const seen = new Set();
865
+ let nextReferenceNumber = 0;
866
+ for (const row of assetRows) {
867
+ const assetId = String(row.asset_id || '').trim();
868
+ if (!assetId)
869
+ continue;
870
+ const rawReferenceNumber = Number(row.reference_number);
871
+ const currentReferenceNumber = Number.isFinite(rawReferenceNumber) && rawReferenceNumber > 0
872
+ ? Math.floor(rawReferenceNumber)
873
+ : null;
874
+ if (currentReferenceNumber && !seen.has(currentReferenceNumber)) {
875
+ seen.add(currentReferenceNumber);
876
+ nextReferenceNumber = Math.max(nextReferenceNumber, currentReferenceNumber);
877
+ continue;
878
+ }
879
+ nextReferenceNumber += 1;
880
+ seen.add(nextReferenceNumber);
881
+ updateReference.run(nextReferenceNumber, tenantId, workspaceId, assetId);
882
+ }
883
+ upsertSequence.run(tenantId, workspaceId, nextReferenceNumber);
884
+ }
885
+ };
886
+ backfillKindReferences('document', 'workspace_document_reference_sequences');
887
+ backfillKindReferences('image', 'workspace_image_reference_sequences');
888
+ db.exec(`
889
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_assets_workspace_kind_reference
890
+ ON workspace_assets(tenant_id, workspace_id, kind, reference_number);
891
+ `);
892
+ }
419
893
  export function ensureSyncEventsSchema(db) {
420
894
  const syncEventsIdColumnSql = db.provider === 'postgres'
421
895
  ? 'id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'
@@ -451,3 +925,171 @@ export function ensureWorkspaceDocumentsSchema(db) {
451
925
  ON workspace_documents(tenant_id, workspace_id, path);
452
926
  `);
453
927
  }
928
+ export function ensureAnnotatedAttachmentSessionsSchema(db) {
929
+ db.exec(`
930
+ CREATE TABLE IF NOT EXISTS annotated_attachment_sessions (
931
+ id TEXT PRIMARY KEY,
932
+ tenant_id TEXT NOT NULL DEFAULT 'default',
933
+ workspace_id TEXT NOT NULL DEFAULT 'default',
934
+ task_id TEXT NOT NULL,
935
+ base_image_asset_id TEXT NOT NULL,
936
+ title TEXT,
937
+ global_instruction TEXT,
938
+ annotations_json TEXT NOT NULL DEFAULT '[]',
939
+ created_by_actor_id TEXT,
940
+ updated_by_actor_id TEXT,
941
+ created_at TEXT NOT NULL,
942
+ updated_at TEXT NOT NULL,
943
+ deleted_at TEXT
944
+ );
945
+
946
+ CREATE INDEX IF NOT EXISTS idx_annotated_attachment_sessions_task
947
+ ON annotated_attachment_sessions(tenant_id, workspace_id, task_id, deleted_at, updated_at);
948
+ CREATE INDEX IF NOT EXISTS idx_annotated_attachment_sessions_image
949
+ ON annotated_attachment_sessions(tenant_id, workspace_id, base_image_asset_id, deleted_at, updated_at);
950
+ `);
951
+ }
952
+ export function ensureDocumentReviewSessionsSchema(db) {
953
+ db.exec(`
954
+ CREATE TABLE IF NOT EXISTS document_review_sessions (
955
+ id TEXT PRIMARY KEY,
956
+ tenant_id TEXT NOT NULL DEFAULT 'default',
957
+ workspace_id TEXT NOT NULL DEFAULT 'default',
958
+ asset_id TEXT NOT NULL,
959
+ document_id TEXT,
960
+ document_version INTEGER,
961
+ title TEXT,
962
+ status TEXT NOT NULL DEFAULT 'open',
963
+ comments_json TEXT NOT NULL DEFAULT '[]',
964
+ created_by_actor_id TEXT,
965
+ updated_by_actor_id TEXT,
966
+ created_at TEXT NOT NULL,
967
+ updated_at TEXT NOT NULL,
968
+ deleted_at TEXT
969
+ );
970
+
971
+ CREATE INDEX IF NOT EXISTS idx_document_review_sessions_asset
972
+ ON document_review_sessions(tenant_id, workspace_id, asset_id, deleted_at, updated_at);
973
+ CREATE INDEX IF NOT EXISTS idx_document_review_sessions_workspace
974
+ ON document_review_sessions(tenant_id, workspace_id, updated_at, id);
975
+
976
+ CREATE TABLE IF NOT EXISTS document_review_comments (
977
+ id TEXT PRIMARY KEY,
978
+ session_id TEXT NOT NULL,
979
+ tenant_id TEXT NOT NULL DEFAULT 'default',
980
+ workspace_id TEXT NOT NULL DEFAULT 'default',
981
+ body TEXT NOT NULL,
982
+ anchor_json TEXT,
983
+ author_actor_id TEXT,
984
+ order_index INTEGER NOT NULL DEFAULT 0,
985
+ created_at TEXT NOT NULL,
986
+ updated_at TEXT NOT NULL,
987
+ deleted_at TEXT
988
+ );
989
+
990
+ CREATE INDEX IF NOT EXISTS idx_document_review_comments_session
991
+ ON document_review_comments(tenant_id, workspace_id, session_id, deleted_at, order_index, created_at, id);
992
+ CREATE INDEX IF NOT EXISTS idx_document_review_comments_workspace
993
+ ON document_review_comments(tenant_id, workspace_id, updated_at, id);
994
+ `);
995
+ const sessionRows = db.prepare(`
996
+ SELECT
997
+ id,
998
+ tenant_id,
999
+ workspace_id,
1000
+ comments_json
1001
+ FROM document_review_sessions
1002
+ WHERE comments_json IS NOT NULL
1003
+ AND TRIM(comments_json) <> ''
1004
+ AND comments_json <> '[]'
1005
+ `).all();
1006
+ const hasExistingComment = db.prepare(`
1007
+ SELECT id
1008
+ FROM document_review_comments
1009
+ WHERE tenant_id = ? AND workspace_id = ? AND session_id = ?
1010
+ LIMIT 1
1011
+ `);
1012
+ const insertComment = db.prepare(`
1013
+ INSERT INTO document_review_comments (
1014
+ id,
1015
+ session_id,
1016
+ tenant_id,
1017
+ workspace_id,
1018
+ body,
1019
+ anchor_json,
1020
+ author_actor_id,
1021
+ order_index,
1022
+ created_at,
1023
+ updated_at,
1024
+ deleted_at
1025
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1026
+ `);
1027
+ for (const row of sessionRows) {
1028
+ const sessionId = String(row.id || '').trim();
1029
+ const tenantId = String(row.tenant_id || 'default').trim() || 'default';
1030
+ const workspaceId = String(row.workspace_id || 'default').trim() || 'default';
1031
+ if (!sessionId)
1032
+ continue;
1033
+ const existing = hasExistingComment.get(tenantId, workspaceId, sessionId);
1034
+ if (existing?.id)
1035
+ continue;
1036
+ try {
1037
+ const parsed = JSON.parse(String(row.comments_json || '[]'));
1038
+ if (!Array.isArray(parsed))
1039
+ continue;
1040
+ for (let index = 0; index < parsed.length; index += 1) {
1041
+ const raw = parsed[index];
1042
+ if (!raw || typeof raw !== 'object')
1043
+ continue;
1044
+ const record = raw;
1045
+ const commentId = String(record.id || '').trim() || `${sessionId}-comment-${index + 1}`;
1046
+ const body = String(record.body || '').trim();
1047
+ if (!body)
1048
+ continue;
1049
+ const createdAt = String(record.createdAt || '').trim() || new Date().toISOString();
1050
+ const updatedAt = String(record.updatedAt || '').trim() || createdAt;
1051
+ const anchorJson = record.anchor && typeof record.anchor === 'object' ? JSON.stringify(record.anchor) : null;
1052
+ const rawOrder = Number(record.order);
1053
+ const orderIndex = Number.isFinite(rawOrder) ? Math.max(0, Math.floor(rawOrder)) : index;
1054
+ insertComment.run(commentId, sessionId, tenantId, workspaceId, body, anchorJson, String(record.authorActorId || '').trim() || null, orderIndex, createdAt, updatedAt, String(record.deletedAt || '').trim() || null);
1055
+ }
1056
+ }
1057
+ catch {
1058
+ continue;
1059
+ }
1060
+ }
1061
+ if (hasTable(db, 'workspace_memberships') && hasTable(db, 'users')) {
1062
+ const anonymousComments = db.prepare(`
1063
+ SELECT DISTINCT tenant_id, workspace_id
1064
+ FROM document_review_comments
1065
+ WHERE LOWER(COALESCE(author_actor_id, '')) = 'anonymous'
1066
+ `).all();
1067
+ const resolveFallbackActor = db.prepare(`
1068
+ SELECT m.user_id
1069
+ FROM workspace_memberships m
1070
+ JOIN users u
1071
+ ON u.tenant_id = m.tenant_id
1072
+ AND u.id = m.user_id
1073
+ WHERE m.tenant_id = ?
1074
+ AND m.workspace_id = ?
1075
+ AND LOWER(COALESCE(m.status, 'active')) = 'active'
1076
+ AND COALESCE(u.is_disabled, 0) = 0
1077
+ ORDER BY COALESCE(m.updated_at, m.created_at) DESC, u.created_at DESC, m.user_id ASC
1078
+ LIMIT 1
1079
+ `);
1080
+ const updateAnonymousComments = db.prepare(`
1081
+ UPDATE document_review_comments
1082
+ SET author_actor_id = ?
1083
+ WHERE tenant_id = ?
1084
+ AND workspace_id = ?
1085
+ AND LOWER(COALESCE(author_actor_id, '')) = 'anonymous'
1086
+ `);
1087
+ for (const row of anonymousComments) {
1088
+ const tenantId = String(row.tenant_id || 'default').trim() || 'default';
1089
+ const workspaceId = String(row.workspace_id || 'default').trim() || 'default';
1090
+ const fallbackActor = resolveFallbackActor.get(tenantId, workspaceId);
1091
+ const actorId = String(fallbackActor?.user_id || 'user').trim() || 'user';
1092
+ updateAnonymousComments.run(actorId, tenantId, workspaceId);
1093
+ }
1094
+ }
1095
+ }