@taskforcehq/taskforce 0.3.305 → 0.3.307

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 (440) hide show
  1. package/README.md +0 -2
  2. package/dist/Taskforce.module.css +603 -107
  3. package/dist/TaskforceCore.js +216 -43
  4. package/dist/TaskforceCore.test.js +611 -28
  5. package/dist/assets/fonts/CourierPrime-Bold.woff2 +0 -0
  6. package/dist/assets/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  7. package/dist/assets/fonts/CourierPrime-Italic.woff2 +0 -0
  8. package/dist/assets/fonts/CourierPrime-Regular.woff2 +0 -0
  9. package/dist/assets/fonts/Noir_medium.woff2 +0 -0
  10. package/dist/assets/fonts/Noir_regular.woff2 +0 -0
  11. package/dist/assets/fonts/RussoOne-Regular.woff2 +0 -0
  12. package/dist/assets/fonts/SpecialElite-Regular.woff2 +0 -0
  13. package/dist/compat/workspaceSyncCompat.js +46 -2
  14. package/dist/compat/workspaceSyncCompat.test.js +38 -1
  15. package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
  16. package/dist/components/activity/EntityActivityTimeline.js +81 -0
  17. package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
  18. package/dist/components/context/ContextAttachmentManager.js +561 -0
  19. package/dist/components/features/AgentsModule.d.ts +14 -1
  20. package/dist/components/features/AgentsModule.js +366 -18
  21. package/dist/components/features/AgentsModule.test.js +507 -8
  22. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
  23. package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
  24. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
  25. package/dist/components/features/DocumentIndex.d.ts +2 -2
  26. package/dist/components/features/DocumentIndex.js +3 -4
  27. package/dist/components/features/DocumentViewer.d.ts +7 -1
  28. package/dist/components/features/DocumentViewer.js +62 -4
  29. package/dist/components/features/DocumentWorkspace.d.ts +10 -2
  30. package/dist/components/features/DocumentWorkspace.js +15 -4
  31. package/dist/components/features/DocumentWorkspace.test.js +51 -1
  32. package/dist/components/features/TaskSettings.d.ts +2 -0
  33. package/dist/components/features/TaskSettings.js +83 -78
  34. package/dist/components/features/TaskSettings.test.js +171 -82
  35. package/dist/components/features/documentWorkspaceModel.d.ts +1 -1
  36. package/dist/components/task/TaskActionHeader.js +11 -5
  37. package/dist/components/task/TaskActionHeader.test.js +10 -0
  38. package/dist/components/task/TaskCard.js +24 -29
  39. package/dist/components/task/TaskCard.test.js +38 -3
  40. package/dist/components/task/TaskContextUpload.js +4 -526
  41. package/dist/components/task/TaskContextUpload.test.js +3 -3
  42. package/dist/components/task/TaskForm.js +61 -116
  43. package/dist/components/task/TaskForm.test.js +110 -8
  44. package/dist/components/task/TaskKanban.d.ts +2 -1
  45. package/dist/components/task/TaskKanban.js +94 -21
  46. package/dist/components/task/TaskKanban.test.js +36 -0
  47. package/dist/components/task/TaskList.js +5 -1
  48. package/dist/components/task/TaskList.test.js +4 -0
  49. package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
  50. package/dist/components/ui/EditableAvatarButton.js +18 -0
  51. package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
  52. package/dist/components/ui/HierarchyActionBadge.js +5 -0
  53. package/dist/components/views/AppShellHeader.d.ts +3 -1
  54. package/dist/components/views/AppShellHeader.js +27 -11
  55. package/dist/components/views/AppShellHeader.test.js +18 -1
  56. package/dist/components/views/PlanComparisonPage.d.ts +9 -1
  57. package/dist/components/views/PlanComparisonPage.js +78 -14
  58. package/dist/components/views/PlanComparisonPage.test.js +257 -0
  59. package/dist/components/views/PlansPage.js +127 -36
  60. package/dist/components/views/PlansPage.test.js +294 -12
  61. package/dist/components/views/StandaloneLayout.js +529 -592
  62. package/dist/components/views/WidgetView.js +10 -8
  63. package/dist/components/views/panels/PlanningDrawer.d.ts +25 -5
  64. package/dist/components/views/panels/PlanningDrawer.js +270 -55
  65. package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
  66. package/dist/components/views/panels/PlanningDrawer.test.js +529 -0
  67. package/dist/components/views/planningScope.d.ts +20 -0
  68. package/dist/components/views/planningScope.js +25 -0
  69. package/dist/components/views/planningScope.test.d.ts +1 -0
  70. package/dist/components/views/planningScope.test.js +60 -0
  71. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +26 -1
  72. package/dist/components/views/standalone/modals/AccountHubModal.js +76 -2
  73. package/dist/components/views/standalone/modals/AccountHubModal.test.js +20 -3
  74. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +20 -0
  75. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +127 -0
  76. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +2 -9
  77. package/dist/components/views/standalone/modals/EditProfileModal.js +3 -2
  78. package/dist/components/views/standalone/modals/SyncEnableWarningModal.d.ts +9 -0
  79. package/dist/components/views/standalone/modals/SyncEnableWarningModal.js +6 -0
  80. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +1 -0
  81. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +24 -0
  82. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +2 -1
  83. package/dist/components/views/standalone/modals/SyncStatusModal.js +2 -2
  84. package/dist/config/envSchema.js +1 -0
  85. package/dist/core/AiProfileService.d.ts +46 -2
  86. package/dist/core/AiProfileService.js +1073 -82
  87. package/dist/core/AiProfileService.test.js +19 -1
  88. package/dist/core/AiProfiles.test.js +1249 -44
  89. package/dist/core/AttachmentLinkService.d.ts +3 -0
  90. package/dist/core/AttachmentLinkService.js +110 -23
  91. package/dist/core/AuthIdentityService.d.ts +107 -0
  92. package/dist/core/AuthIdentityService.js +284 -0
  93. package/dist/core/AuthTokenService.d.ts +4 -0
  94. package/dist/core/AuthTokenService.js +34 -6
  95. package/dist/core/AuthTokenService.test.js +3 -3
  96. package/dist/core/EntitlementsPolicy.test.js +2 -2
  97. package/dist/core/GlobalSettingsService.js +127 -6
  98. package/dist/core/McpTokenService.d.ts +12 -0
  99. package/dist/core/McpTokenService.js +44 -1
  100. package/dist/core/PlanEntitlementService.d.ts +23 -2
  101. package/dist/core/PlanEntitlementService.js +343 -57
  102. package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
  103. package/dist/core/PlanFeatureCatalog.test.js +84 -0
  104. package/dist/core/PlanVersionPolicy.test.js +35 -2
  105. package/dist/core/PlanningEntities.test.js +418 -4
  106. package/dist/core/SignupMonetizationSettings.test.js +199 -27
  107. package/dist/core/SyncReconciliationService.js +2 -65
  108. package/dist/core/SystemAdmin.test.js +42 -42
  109. package/dist/core/TaskActivityService.d.ts +28 -1
  110. package/dist/core/TaskActivityService.js +227 -46
  111. package/dist/core/TaskActivitySync.test.d.ts +1 -0
  112. package/dist/core/TaskActivitySync.test.js +90 -0
  113. package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
  114. package/dist/core/TaskAuditTimeline.test.js +96 -0
  115. package/dist/core/Taskforce.d.ts +415 -40
  116. package/dist/core/Taskforce.ids.test.js +58 -0
  117. package/dist/core/Taskforce.js +1543 -266
  118. package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
  119. package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
  120. package/dist/core/Taskforce.mcpAuth.test.js +109 -0
  121. package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
  122. package/dist/core/WorkspaceLifecycleService.js +0 -5
  123. package/dist/core/WorkspacePermissions.test.js +25 -1
  124. package/dist/core/WorkspacePlanMode.test.js +117 -16
  125. package/dist/core/shared.d.ts +1 -1
  126. package/dist/core/shared.js +5 -1
  127. package/dist/core/types.d.ts +75 -2
  128. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +28 -2
  129. package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
  130. package/dist/hooks/bootstrapTimeouts.js +8 -0
  131. package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
  132. package/dist/hooks/bootstrapTimeouts.test.js +12 -0
  133. package/dist/hooks/sync/bootstrap.js +2 -0
  134. package/dist/hooks/sync/controlPlane.d.ts +37 -0
  135. package/dist/hooks/sync/controlPlane.js +78 -0
  136. package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
  137. package/dist/hooks/sync/controlPlane.test.js +121 -0
  138. package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
  139. package/dist/hooks/sync/lifecyclePolicy.js +93 -0
  140. package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
  141. package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
  142. package/dist/hooks/sync/orchestratorShared.d.ts +13 -4
  143. package/dist/hooks/sync/orchestratorShared.js +129 -48
  144. package/dist/hooks/sync/orchestratorShared.test.js +50 -1
  145. package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
  146. package/dist/hooks/sync/pullLifecycle.js +24 -0
  147. package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
  148. package/dist/hooks/sync/pullLifecycle.test.js +80 -0
  149. package/dist/hooks/sync/recovery.d.ts +16 -2
  150. package/dist/hooks/sync/recovery.js +179 -53
  151. package/dist/hooks/sync/recovery.test.d.ts +1 -0
  152. package/dist/hooks/sync/recovery.test.js +292 -0
  153. package/dist/hooks/sync/transfers.d.ts +16 -3
  154. package/dist/hooks/sync/transfers.js +210 -66
  155. package/dist/hooks/sync/transfers.test.d.ts +1 -0
  156. package/dist/hooks/sync/transfers.test.js +928 -0
  157. package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
  158. package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
  159. package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
  160. package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
  161. package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
  162. package/dist/hooks/sync/useSyncStatusActions.js +88 -0
  163. package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
  164. package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
  165. package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
  166. package/dist/hooks/sync/useSyncStatusControls.js +60 -0
  167. package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
  168. package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
  169. package/dist/hooks/useFilterSort.js +13 -13
  170. package/dist/hooks/useFilterSort.test.js +87 -1
  171. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
  172. package/dist/hooks/useSyncOrchestrator.d.ts +9 -2
  173. package/dist/hooks/useSyncOrchestrator.js +409 -183
  174. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +407 -0
  175. package/dist/hooks/useTaskData.js +8 -3
  176. package/dist/hooks/useTaskData.test.js +45 -0
  177. package/dist/hooks/useTaskforce.d.ts +145 -52
  178. package/dist/hooks/useTaskforce.js +592 -253
  179. package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
  180. package/dist/hooks/useTaskforce.runtime-routing.test.js +246 -0
  181. package/dist/hooks/useTaskforce.sync-behavior.test.js +2468 -201
  182. package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
  183. package/dist/hooks/useWorkspaceSyncController.js +13 -2
  184. package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
  185. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
  186. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +328 -40
  187. package/dist/localization/locales/en-US.d.ts +0 -1
  188. package/dist/localization/locales/en-US.js +0 -1
  189. package/dist/localization/locales/es-419.js +0 -1
  190. package/dist/localization/locales/pt-BR.js +0 -1
  191. package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
  192. package/dist/mcp/canonicalAssetHelpers.js +18 -10
  193. package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
  194. package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
  195. package/dist/mcp/clientIntegrations.d.ts +1 -0
  196. package/dist/mcp/clientIntegrations.js +25 -0
  197. package/dist/mcp/clientIntegrations.test.js +14 -3
  198. package/dist/mcp/clientProfileDefaults.js +3 -3
  199. package/dist/mcp/collaborationRegistrar.js +7 -7
  200. package/dist/mcp/documentAssetRegistrar.js +116 -10
  201. package/dist/mcp/runtime.d.ts +3 -0
  202. package/dist/mcp/runtime.js +1099 -185
  203. package/dist/mcp/runtime.test.js +1491 -140
  204. package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
  205. package/dist/mcp/taskPlanningRegistrar.js +48 -0
  206. package/dist/mcp/toolRegistry.d.ts +56 -0
  207. package/dist/mcp/toolRegistry.js +8 -0
  208. package/dist/mcp/toolRegistry.test.js +4 -0
  209. package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
  210. package/dist/migrations/taskSchemaMigrations.js +192 -61
  211. package/dist/migrations/taskSchemaMigrations.test.js +15 -0
  212. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  213. package/dist/resources/templates/workflows/collaborate.yaml +1 -1
  214. package/dist/resources/templates/workflows/evaluate.yaml +2 -2
  215. package/dist/resources/templates/workflows/plan.yaml +1 -1
  216. package/dist/resources/templates/workflows/review.yaml +2 -2
  217. package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
  218. package/dist/server/aiProfileAvatarAssets.js +319 -0
  219. package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
  220. package/dist/server/aiProfileAvatarAssets.test.js +213 -0
  221. package/dist/server/annotatedAttachmentsRoutes.test.js +69 -10
  222. package/dist/server/auth/providers/apple.d.ts +33 -0
  223. package/dist/server/auth/providers/apple.js +82 -0
  224. package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
  225. package/dist/server/auth/providers/appleClientSecret.js +65 -0
  226. package/dist/server/auth/providers/github.d.ts +26 -0
  227. package/dist/server/auth/providers/github.js +86 -0
  228. package/dist/server/auth/providers/google.d.ts +21 -0
  229. package/dist/server/auth/providers/google.js +56 -0
  230. package/dist/server/auth/providers/types.d.ts +21 -0
  231. package/dist/server/auth/providers/types.js +1 -0
  232. package/dist/server/auth.d.ts +2 -0
  233. package/dist/server/auth.js +6 -3
  234. package/dist/server/documentReviewRoutes.test.js +36 -3
  235. package/dist/server/index.cookieProxy.test.js +1 -0
  236. package/dist/server/index.d.ts +12 -0
  237. package/dist/server/index.js +124 -9
  238. package/dist/server/index.rateLimit.test.js +3 -0
  239. package/dist/server/index.test.js +111 -3
  240. package/dist/server/routes/admin.d.ts +3 -0
  241. package/dist/server/routes/admin.js +459 -28
  242. package/dist/server/routes/annotatedAttachments.js +51 -0
  243. package/dist/server/routes/auth.d.ts +26 -2
  244. package/dist/server/routes/auth.js +1170 -71
  245. package/dist/server/routes/authSupport.d.ts +5 -1
  246. package/dist/server/routes/authSupport.js +13 -2
  247. package/dist/server/routes/billing.js +372 -35
  248. package/dist/server/routes/billing.test.js +595 -12
  249. package/dist/server/routes/documents.d.ts +1 -0
  250. package/dist/server/routes/documents.js +182 -70
  251. package/dist/server/routes/shared.d.ts +28 -2
  252. package/dist/server/routes/shared.js +69 -14
  253. package/dist/server/routes/sync.integration.test.js +658 -39
  254. package/dist/server/routes/sync.js +74 -608
  255. package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
  256. package/dist/server/routes/syncAuxRoutes.js +91 -0
  257. package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
  258. package/dist/server/routes/syncAuxRoutes.test.js +158 -0
  259. package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
  260. package/dist/server/routes/syncPullApplyRoutes.js +204 -0
  261. package/dist/server/routes/syncPushRoutes.d.ts +24 -0
  262. package/dist/server/routes/syncPushRoutes.js +212 -0
  263. package/dist/server/routes/syncRouteGuards.d.ts +36 -0
  264. package/dist/server/routes/syncRouteGuards.js +67 -0
  265. package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
  266. package/dist/server/routes/syncRouteGuards.test.js +94 -0
  267. package/dist/server/routes/syncRouteTypes.d.ts +13 -0
  268. package/dist/server/routes/syncRouteTypes.js +1 -0
  269. package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
  270. package/dist/server/routes/syncSnapshotRoutes.js +182 -0
  271. package/dist/server/routes/tasks.js +55 -10
  272. package/dist/server/routes/workspaces.js +36 -5
  273. package/dist/server/routes.js +147 -11
  274. package/dist/server/routes.test.js +2704 -183
  275. package/dist/services/workflowExportSnapshots.test.js +2 -0
  276. package/dist/shared/aiProfileSeatScope.d.ts +5 -0
  277. package/dist/shared/aiProfileSeatScope.js +21 -0
  278. package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
  279. package/dist/shared/aiProfileSurfaceType.js +10 -8
  280. package/dist/shared/passwordPolicy.d.ts +13 -0
  281. package/dist/shared/passwordPolicy.js +84 -0
  282. package/dist/shared/passwordPolicy.test.d.ts +1 -0
  283. package/dist/shared/passwordPolicy.test.js +34 -0
  284. package/dist/storage/objectStorage.d.ts +1 -0
  285. package/dist/storage/objectStorage.js +2 -1
  286. package/dist/storage/objectStorageClient.d.ts +1 -0
  287. package/dist/storage/objectStorageClient.js +41 -8
  288. package/dist/storage/objectStorageClient.test.js +26 -1
  289. package/dist/storage/objectStorageConfig.js +3 -1
  290. package/dist/storage/objectStorageConfig.test.js +13 -1
  291. package/dist/storage/workspaceAssetStore.d.ts +15 -3
  292. package/dist/storage/workspaceAssetStore.js +132 -44
  293. package/dist/storage/workspaceAssetStore.test.js +93 -6
  294. package/dist/styles/fonts.css +70 -0
  295. package/dist/sync/collaborationSyncPayload.d.ts +6 -1
  296. package/dist/sync/collaborationSyncPayload.js +19 -11
  297. package/dist/sync/collaborationSyncPayload.test.js +14 -1
  298. package/dist/sync/collaborationSyncState.d.ts +3 -3
  299. package/dist/sync/collaborationSyncState.js +19 -12
  300. package/dist/sync/contentSyncPayload.d.ts +5 -1
  301. package/dist/sync/contentSyncPayload.js +9 -0
  302. package/dist/sync/contentSyncPayload.test.js +39 -0
  303. package/dist/sync/contentSyncState.d.ts +9 -9
  304. package/dist/sync/contentSyncState.js +248 -107
  305. package/dist/sync/planningSyncPayload.js +5 -0
  306. package/dist/sync/planningSyncPayload.test.js +24 -0
  307. package/dist/sync/syncApplyHandlers.d.ts +11 -4
  308. package/dist/sync/syncApplyHandlers.js +115 -42
  309. package/dist/sync/syncApplyHandlers.test.js +251 -4
  310. package/dist/sync/syncFieldSemantics.d.ts +12 -0
  311. package/dist/sync/syncFieldSemantics.js +55 -0
  312. package/dist/sync/syncResourceAdapters.d.ts +46 -0
  313. package/dist/sync/syncResourceAdapters.js +79 -0
  314. package/dist/sync/syncService.d.ts +6 -0
  315. package/dist/sync/syncService.js +65 -1
  316. package/dist/sync/syncService.test.js +96 -3
  317. package/dist/sync/taskSyncChangeKey.d.ts +2 -0
  318. package/dist/sync/taskSyncChangeKey.js +143 -0
  319. package/dist/sync/taskSyncPayload.js +3 -8
  320. package/dist/sync/workspacePullFeed.d.ts +4 -0
  321. package/dist/sync/workspacePullFeed.js +132 -72
  322. package/dist/sync/workspacePullFeed.test.js +92 -0
  323. package/dist/sync/workspaceRepair.js +5 -2
  324. package/dist/sync/workspaceSyncModel.d.ts +73 -6
  325. package/dist/sync/workspaceSyncModel.js +342 -73
  326. package/dist/sync/workspaceSyncModel.test.js +559 -14
  327. package/dist/sync/workspaceSyncState.d.ts +17 -0
  328. package/dist/sync/workspaceSyncState.js +2 -1
  329. package/dist/sync/workspaceSyncSurface.js +3 -8
  330. package/dist/types.d.ts +50 -2
  331. package/dist/ui/assets/AgentsModule-2y82_3DO.js +1 -0
  332. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTLZZCiQ.js +3 -0
  333. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
  334. package/dist/ui/assets/ContextAttachmentManager-D2epuNnG.js +3 -0
  335. package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
  336. package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
  337. package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
  338. package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
  339. package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
  340. package/dist/ui/assets/DocumentWorkspace-sVa-3Do6.js +252 -0
  341. package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
  342. package/dist/ui/assets/EntityActivityTimeline-Zods27y_.js +1 -0
  343. package/dist/ui/assets/{InitiativesModule-Dhm7M8e7.js → InitiativesModule-D4XseTwW.js} +1 -1
  344. package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
  345. package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
  346. package/dist/ui/assets/PlansPage-D5AcbO0L.js +1 -0
  347. package/dist/ui/assets/PlansPage-Dvqsz5zc.css +1 -0
  348. package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
  349. package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
  350. package/dist/ui/assets/TaskContextUpload-uC5qx4Bv.js +1 -0
  351. package/dist/ui/assets/TaskSettings-CqvPAsTv.js +9 -0
  352. package/dist/ui/assets/{WorkflowsModule-BcS4afRn.js → WorkflowsModule-oOA9bcdK.js} +4 -4
  353. package/dist/ui/assets/documentReferences-DPZuTgHh.js +1 -0
  354. package/dist/ui/assets/index-607WPo_X.js +4 -0
  355. package/dist/ui/assets/index-CYyodXsg.css +1 -0
  356. package/dist/ui/assets/{vendor-icons-BSUaRwF8.js → vendor-icons-B32hGuF2.js} +1 -1
  357. package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
  358. package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
  359. package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
  360. package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  361. package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
  362. package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
  363. package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
  364. package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
  365. package/dist/ui/fonts/Noir_medium.otf +0 -0
  366. package/dist/ui/fonts/Noir_medium.woff2 +0 -0
  367. package/dist/ui/fonts/Noir_regular.otf +0 -0
  368. package/dist/ui/fonts/Noir_regular.woff2 +0 -0
  369. package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
  370. package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
  371. package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
  372. package/dist/ui/index.html +3 -3
  373. package/dist/ui/product/agent manager.png +0 -0
  374. package/dist/ui/product/agent_manager_02.png +0 -0
  375. package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
  376. package/dist/utils/aiProfileEvents.d.ts +7 -0
  377. package/dist/utils/aiProfileEvents.js +6 -0
  378. package/dist/utils/assignees.d.ts +8 -0
  379. package/dist/utils/assignees.js +10 -1
  380. package/dist/utils/assignees.test.d.ts +1 -0
  381. package/dist/utils/assignees.test.js +25 -0
  382. package/dist/utils/avatarDisplay.d.ts +1 -0
  383. package/dist/utils/avatarDisplay.js +15 -0
  384. package/dist/utils/avatarUpload.d.ts +27 -0
  385. package/dist/utils/avatarUpload.js +132 -0
  386. package/dist/utils/avatarUpload.test.d.ts +1 -0
  387. package/dist/utils/avatarUpload.test.js +40 -0
  388. package/dist/utils/bootstrapTrace.d.ts +7 -0
  389. package/dist/utils/bootstrapTrace.js +29 -0
  390. package/dist/utils/commercialLifecyclePresentation.js +3 -0
  391. package/dist/utils/contextAssetEvents.d.ts +2 -0
  392. package/dist/utils/contextFiles.d.ts +3 -1
  393. package/dist/utils/contextFiles.js +2 -1
  394. package/dist/utils/syncEventDetails.d.ts +3 -0
  395. package/dist/utils/syncEventDetails.js +64 -0
  396. package/dist/utils/syncEventDetails.test.d.ts +1 -0
  397. package/dist/utils/syncEventDetails.test.js +23 -0
  398. package/dist/utils/syncEventPresentation.d.ts +15 -0
  399. package/dist/utils/syncEventPresentation.js +129 -0
  400. package/dist/utils/syncEventPresentation.test.d.ts +1 -0
  401. package/dist/utils/syncEventPresentation.test.js +64 -0
  402. package/dist/utils/syncStatusPresentation.d.ts +72 -0
  403. package/dist/utils/syncStatusPresentation.js +217 -0
  404. package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
  405. package/dist/utils/syncStatusPresentation.test.js +164 -0
  406. package/dist/utils/taskActivity.d.ts +9 -1
  407. package/dist/utils/taskActivity.js +290 -22
  408. package/dist/utils/taskActivity.test.js +141 -8
  409. package/dist/utils/taskSearch.d.ts +22 -0
  410. package/dist/utils/taskSearch.js +87 -0
  411. package/dist/utils/taskSearch.test.d.ts +1 -0
  412. package/dist/utils/taskSearch.test.js +69 -0
  413. package/dist/utils/taskUtils.js +10 -3
  414. package/dist/utils/taskUtils.test.d.ts +1 -0
  415. package/dist/utils/taskUtils.test.js +19 -0
  416. package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
  417. package/dist/utils/workspaceSyncPresentation.js +68 -2
  418. package/dist/utils/workspaceSyncPresentation.test.js +36 -1
  419. package/package.json +3 -2
  420. package/scripts/export-sqlite-to-postgres.mjs +7 -9
  421. package/scripts/run-e2e-realtime.sh +17 -3
  422. package/scripts/run-smoke.sh +17 -5
  423. package/scripts/run-soak.sh +17 -5
  424. package/src/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  425. package/src/resources/templates/workflows/collaborate.yaml +1 -1
  426. package/src/resources/templates/workflows/evaluate.yaml +2 -2
  427. package/src/resources/templates/workflows/plan.yaml +1 -1
  428. package/src/resources/templates/workflows/review.yaml +2 -2
  429. package/dist/ui/assets/AgentsModule-N2MnQBZk.js +0 -1
  430. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BG6P_GVW.js +0 -3
  431. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
  432. package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +0 -1
  433. package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +0 -252
  434. package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
  435. package/dist/ui/assets/PlansPage-Cq0zXj3I.js +0 -1
  436. package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
  437. package/dist/ui/assets/TaskSettings-ln0aF7xc.js +0 -9
  438. package/dist/ui/assets/index-C2-OXZV7.css +0 -1
  439. package/dist/ui/assets/index-DcSI5F86.js +0 -6
  440. package/scripts/migrate-planning-model.ts +0 -233
@@ -0,0 +1,561 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { AlertTriangle, Copy, Download, File, FileUp, Loader2, PencilLine, Trash2, ChevronDown, ChevronRight } from 'lucide-react';
4
+ import styles from '../../Taskforce.module.css';
5
+ import { dispatchOpenMarkdownDocument } from '../../utils/contextFiles';
6
+ import { canOpenAnnotatedAttachment, dispatchOpenAnnotatedAttachment } from '../../utils/annotatedAttachments';
7
+ import { dispatchTaskforceContextAssetsMutated } from '../../utils/contextAssetEvents';
8
+ import { getDocumentReferenceLabel } from '../../utils/documentReferences';
9
+ const ACCEPTED_CONTEXT_FILE_TYPES = [
10
+ '.png', '.jpg', '.jpeg', '.webp', '.gif',
11
+ '.pdf', '.txt', '.md', '.csv', '.json', '.doc', '.docx',
12
+ '.html', '.js', '.ts', '.tsx', '.css', '.py', '.java', '.go', '.rs', '.sh'
13
+ ].join(',');
14
+ const SUPPORTED_CLIPBOARD_IMAGE_TYPES = new Set(['image/png', 'image/jpeg', 'image/webp']);
15
+ const ACCEPTED_CONTEXT_EXTENSIONS = new Set(ACCEPTED_CONTEXT_FILE_TYPES.split(',').map((ext) => ext.trim().toLowerCase()));
16
+ const MAX_CONTEXT_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10 MB per file
17
+ const CONTEXT_NOTICE_TIMEOUT_MS = 3500;
18
+ function getFileExtension(fileName) {
19
+ const trimmed = fileName.trim().toLowerCase();
20
+ const dotIdx = trimmed.lastIndexOf('.');
21
+ if (dotIdx === -1)
22
+ return '';
23
+ return trimmed.slice(dotIdx);
24
+ }
25
+ function formatFileList(fileNames) {
26
+ if (fileNames.length === 0)
27
+ return '';
28
+ const shown = fileNames.slice(0, 3).join(', ');
29
+ const extra = fileNames.length - 3;
30
+ return extra > 0 ? `${shown}, +${extra} more` : shown;
31
+ }
32
+ function getLocalFileFingerprint(file) {
33
+ return `${file.name.trim().toLowerCase()}::${file.size}::${file.lastModified}`;
34
+ }
35
+ function readFileAsDataUrl(file) {
36
+ return new Promise((resolve, reject) => {
37
+ const reader = new FileReader();
38
+ reader.onload = () => resolve(String(reader.result || ''));
39
+ reader.onerror = () => reject(reader.error || new Error('Failed to read file'));
40
+ reader.readAsDataURL(file);
41
+ });
42
+ }
43
+ function isImagePath(path) {
44
+ return /\.(png|jpe?g|webp|gif)(\?|#|$)/i.test(path);
45
+ }
46
+ function getClipboardImageType(item) {
47
+ const rawTypes = item.types;
48
+ if (!rawTypes)
49
+ return null;
50
+ for (const type of Array.from(rawTypes)) {
51
+ const normalizedType = String(type || '').trim().toLowerCase();
52
+ if (SUPPORTED_CLIPBOARD_IMAGE_TYPES.has(normalizedType)) {
53
+ return normalizedType;
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ function buildDownloadUrl(pathValue, displayName) {
59
+ const separator = pathValue.includes('?') ? '&' : '?';
60
+ return `${pathValue}${separator}download=1&filename=${encodeURIComponent(displayName)}`;
61
+ }
62
+ function getAttachmentDisplayName(item) {
63
+ if (typeof item === 'string')
64
+ return item.split('/').pop() || 'Context file';
65
+ return item.displayName || item.originalFilename || item.caption || item.fsPath || item.path.split('/').pop() || 'Context file';
66
+ }
67
+ function getAttachmentTypeLabel(item) {
68
+ const candidates = typeof item === 'string'
69
+ ? [item]
70
+ : [item.originalFilename, item.displayName, item.caption, item.fsPath, item.path];
71
+ for (const candidate of candidates) {
72
+ if (!candidate)
73
+ continue;
74
+ const ext = getFileExtension(candidate);
75
+ if (ext)
76
+ return ext.replace('.', '').slice(0, 5).toUpperCase();
77
+ }
78
+ const path = typeof item === 'string' ? item : item.path;
79
+ return /^https?:\/\//i.test(path) ? 'LINK' : 'FILE';
80
+ }
81
+ export function ContextAttachmentManager(props) {
82
+ const { ownerType = 'task', ownerId, ownerReferenceLabel, workspaceId, attachments, onAddAttachment, onRemoveAttachment, onUpdateAttachmentCaption, } = props;
83
+ const inputRef = useRef(null);
84
+ const [uploading, setUploading] = useState(false);
85
+ const [uploadError, setUploadError] = useState(null);
86
+ const [linkValue, setLinkValue] = useState('');
87
+ const [linkError, setLinkError] = useState(null);
88
+ const [contextNotice, setContextNotice] = useState(null);
89
+ const [showContextUpload, setShowContextUpload] = useState(false);
90
+ const [isDropActive, setIsDropActive] = useState(false);
91
+ const [dragDepth, setDragDepth] = useState(0);
92
+ const contextKeyRef = useRef(new Set());
93
+ const localUploadFingerprintRef = useRef(new Set());
94
+ const normalizeKey = (value) => (value || '').trim();
95
+ const getContextKeys = (path, fsPath) => {
96
+ const keys = [];
97
+ const normalizedPath = normalizeKey(path);
98
+ const normalizedFsPath = normalizeKey(fsPath);
99
+ if (normalizedPath)
100
+ keys.push(`path:${normalizedPath}`);
101
+ if (normalizedFsPath)
102
+ keys.push(`fs:${normalizedFsPath}`);
103
+ return keys;
104
+ };
105
+ const keySetFromFiles = useMemo(() => {
106
+ const next = new Set();
107
+ attachments.forEach((item) => {
108
+ if (typeof item === 'string') {
109
+ getContextKeys(item).forEach((key) => next.add(key));
110
+ return;
111
+ }
112
+ getContextKeys(item.path, item.fsPath).forEach((key) => next.add(key));
113
+ });
114
+ return next;
115
+ }, [attachments]);
116
+ useEffect(() => {
117
+ contextKeyRef.current = new Set(keySetFromFiles);
118
+ }, [keySetFromFiles]);
119
+ const hasAnyKey = (set, keys) => keys.some((key) => set.has(key));
120
+ const addKeys = (set, keys) => keys.forEach((key) => set.add(key));
121
+ const trimmedWorkspaceId = String(workspaceId || '').trim();
122
+ const trimmedOwnerId = String(ownerId || '').trim();
123
+ const ownerTypeLabel = ownerType === 'initiative'
124
+ ? 'initiative'
125
+ : ownerType === 'workstream'
126
+ ? 'workstream'
127
+ : 'task';
128
+ const ownerUploadPayload = {
129
+ ownerType,
130
+ ownerId: trimmedOwnerId || null,
131
+ taskId: ownerType === 'task' ? (trimmedOwnerId || null) : null,
132
+ };
133
+ const buildApiHeaders = (contentType = 'application/json') => {
134
+ const headers = { 'Content-Type': contentType };
135
+ if (trimmedWorkspaceId)
136
+ headers['x-taskforce-workspace-id'] = trimmedWorkspaceId;
137
+ return headers;
138
+ };
139
+ const addLink = (rawValue, clearInput = true, contextKeySet = contextKeyRef.current) => {
140
+ const trimmed = rawValue.trim();
141
+ if (!trimmed)
142
+ return 'invalid';
143
+ const isHttp = /^https?:\/\//i.test(trimmed);
144
+ if (!isHttp)
145
+ return 'invalid';
146
+ const normalizedPath = trimmed;
147
+ const keys = getContextKeys(normalizedPath);
148
+ if (hasAnyKey(contextKeySet, keys))
149
+ return 'duplicate';
150
+ const nameFromPath = trimmed.split(/[\\/]/).pop() || trimmed;
151
+ onAddAttachment({
152
+ path: normalizedPath,
153
+ caption: nameFromPath,
154
+ timestamp: new Date().toISOString()
155
+ });
156
+ addKeys(contextKeySet, keys);
157
+ if (clearInput)
158
+ setLinkValue('');
159
+ setLinkError(null);
160
+ return 'added';
161
+ };
162
+ useEffect(() => {
163
+ if (!contextNotice)
164
+ return;
165
+ const timeoutId = window.setTimeout(() => {
166
+ setContextNotice(null);
167
+ }, CONTEXT_NOTICE_TIMEOUT_MS);
168
+ return () => window.clearTimeout(timeoutId);
169
+ }, [contextNotice]);
170
+ const handleSelectedFiles = async (selectedFilesInput) => {
171
+ if (selectedFilesInput.length === 0)
172
+ return;
173
+ setUploadError(null);
174
+ setContextNotice(null);
175
+ const selectedFiles = selectedFilesInput;
176
+ const unsupportedFiles = [];
177
+ const oversizedFiles = [];
178
+ const localDuplicateFiles = [];
179
+ const uploadCandidates = [];
180
+ const localFingerprintSet = new Set(localUploadFingerprintRef.current);
181
+ selectedFiles.forEach((file) => {
182
+ const ext = getFileExtension(file.name);
183
+ if (!ACCEPTED_CONTEXT_EXTENSIONS.has(ext)) {
184
+ unsupportedFiles.push(file.name);
185
+ return;
186
+ }
187
+ if (file.size > MAX_CONTEXT_FILE_SIZE_BYTES) {
188
+ oversizedFiles.push(file.name);
189
+ return;
190
+ }
191
+ const fingerprint = getLocalFileFingerprint(file);
192
+ if (localFingerprintSet.has(fingerprint)) {
193
+ localDuplicateFiles.push(file.name);
194
+ return;
195
+ }
196
+ localFingerprintSet.add(fingerprint);
197
+ uploadCandidates.push({ file, fingerprint });
198
+ });
199
+ const validationNotices = [];
200
+ if (unsupportedFiles.length > 0) {
201
+ validationNotices.push(`${unsupportedFiles.length} unsupported file${unsupportedFiles.length === 1 ? '' : 's'} skipped: ${formatFileList(unsupportedFiles)}.`);
202
+ }
203
+ if (oversizedFiles.length > 0) {
204
+ validationNotices.push(`${oversizedFiles.length} file${oversizedFiles.length === 1 ? '' : 's'} over 10 MB skipped: ${formatFileList(oversizedFiles)}.`);
205
+ }
206
+ if (localDuplicateFiles.length > 0) {
207
+ validationNotices.push(`${localDuplicateFiles.length} local duplicate file${localDuplicateFiles.length === 1 ? '' : 's'} skipped before upload: ${formatFileList(localDuplicateFiles)}.`);
208
+ }
209
+ if (uploadCandidates.length === 0) {
210
+ if (validationNotices.length > 0)
211
+ setContextNotice(validationNotices.join(' '));
212
+ if (inputRef.current)
213
+ inputRef.current.value = '';
214
+ return;
215
+ }
216
+ setUploading(true);
217
+ const contextKeySet = new Set(contextKeyRef.current);
218
+ let duplicateCount = 0;
219
+ try {
220
+ for (const { file, fingerprint } of uploadCandidates) {
221
+ let data = null;
222
+ // Keep uploads same-origin so local runtime never routes attachments through the cloud API base.
223
+ const initRes = await fetch('/api/taskforce/context-upload/init', {
224
+ method: 'POST',
225
+ headers: buildApiHeaders(),
226
+ body: JSON.stringify({
227
+ originalName: file.name,
228
+ mimeType: file.type || 'application/octet-stream',
229
+ size: file.size,
230
+ ...ownerUploadPayload,
231
+ workspaceId: trimmedWorkspaceId || null
232
+ })
233
+ });
234
+ if (initRes.ok) {
235
+ const initData = await initRes.json();
236
+ if (initData?.success && typeof initData?.uploadUrl === 'string' && typeof initData?.path === 'string') {
237
+ const uploadRes = await fetch(initData.uploadUrl, {
238
+ method: String(initData.method || 'PUT'),
239
+ headers: initData.headers || { 'Content-Type': file.type || 'application/octet-stream' },
240
+ body: file
241
+ });
242
+ if (!uploadRes.ok) {
243
+ throw new Error(`Upload failed for ${file.name}`);
244
+ }
245
+ const finalizeRes = await fetch('/api/taskforce/context-upload/finalize', {
246
+ method: 'POST',
247
+ headers: buildApiHeaders(),
248
+ body: JSON.stringify({
249
+ relativePath: initData.relativePath,
250
+ mimeType: file.type || 'application/octet-stream',
251
+ originalName: file.name,
252
+ size: file.size,
253
+ ...ownerUploadPayload,
254
+ workspaceId: trimmedWorkspaceId || null
255
+ })
256
+ });
257
+ if (!finalizeRes.ok) {
258
+ const finalizeError = await finalizeRes.json().catch(() => ({}));
259
+ throw new Error(finalizeError?.error || `Upload failed for ${file.name}`);
260
+ }
261
+ data = await finalizeRes.json().catch(() => null);
262
+ }
263
+ else if (initData?.success && typeof initData?.path === 'string') {
264
+ data = initData;
265
+ }
266
+ }
267
+ if (!data) {
268
+ const encoded = await readFileAsDataUrl(file);
269
+ const res = await fetch('/api/taskforce/context-upload', {
270
+ method: 'POST',
271
+ headers: buildApiHeaders(),
272
+ body: JSON.stringify({
273
+ file: encoded,
274
+ originalName: file.name,
275
+ ...ownerUploadPayload,
276
+ workspaceId: trimmedWorkspaceId || null
277
+ })
278
+ });
279
+ if (!res.ok) {
280
+ throw new Error(`Upload failed for ${file.name}`);
281
+ }
282
+ data = await res.json();
283
+ }
284
+ if (!data?.success || !data?.path) {
285
+ throw new Error(`Upload failed for ${file.name}`);
286
+ }
287
+ const keys = getContextKeys(data.path, data.fsPath);
288
+ if (hasAnyKey(contextKeySet, keys)) {
289
+ duplicateCount += 1;
290
+ continue;
291
+ }
292
+ onAddAttachment({
293
+ path: data.path,
294
+ fsPath: data.fsPath,
295
+ caption: typeof data.caption === 'string' && data.caption.trim().length > 0 ? data.caption : file.name,
296
+ displayName: typeof data.displayName === 'string' ? data.displayName : undefined,
297
+ originalFilename: typeof data.originalFilename === 'string' ? data.originalFilename : file.name,
298
+ assetId: typeof data.assetId === 'string' ? data.assetId : undefined,
299
+ referenceNumber: typeof data.referenceNumber === 'number' ? data.referenceNumber : null,
300
+ referenceLabel: typeof data.referenceLabel === 'string' ? data.referenceLabel : undefined,
301
+ taskId: ownerType === 'task' && typeof data.taskId === 'string' ? data.taskId : null,
302
+ timestamp: typeof data.timestamp === 'string' && data.timestamp.trim().length > 0
303
+ ? data.timestamp
304
+ : new Date().toISOString()
305
+ });
306
+ dispatchTaskforceContextAssetsMutated({
307
+ workspaceId: trimmedWorkspaceId || 'default',
308
+ ownerType,
309
+ ownerId: trimmedOwnerId || null,
310
+ taskId: ownerType === 'task' ? (trimmedOwnerId || null) : null,
311
+ reason: 'upload'
312
+ });
313
+ addKeys(contextKeySet, keys);
314
+ localUploadFingerprintRef.current.add(fingerprint);
315
+ }
316
+ const notices = [...validationNotices];
317
+ if (duplicateCount > 0) {
318
+ notices.push(`${duplicateCount} duplicate file${duplicateCount === 1 ? '' : 's'} skipped.`);
319
+ }
320
+ setContextNotice(notices.length > 0 ? notices.join(' ') : null);
321
+ contextKeyRef.current = contextKeySet;
322
+ }
323
+ catch (error) {
324
+ setUploadError(error instanceof Error ? error.message : 'Failed to upload context file');
325
+ }
326
+ finally {
327
+ setUploading(false);
328
+ if (inputRef.current)
329
+ inputRef.current.value = '';
330
+ }
331
+ };
332
+ const handleFilesSelected = async (files) => {
333
+ if (!files || files.length === 0)
334
+ return;
335
+ await handleSelectedFiles(Array.from(files));
336
+ };
337
+ const handlePasteImage = async () => {
338
+ setUploadError(null);
339
+ setContextNotice(null);
340
+ if (!navigator.clipboard || typeof navigator.clipboard.read !== 'function') {
341
+ setUploadError('Clipboard image paste is not available in this browser.');
342
+ return;
343
+ }
344
+ try {
345
+ const clipboardItems = await navigator.clipboard.read();
346
+ const imageFiles = [];
347
+ for (const item of clipboardItems) {
348
+ const imageType = getClipboardImageType(item);
349
+ if (!imageType)
350
+ continue;
351
+ const blob = await item.getType(imageType);
352
+ const extension = imageType.toLowerCase() === 'image/png'
353
+ ? 'png'
354
+ : imageType.toLowerCase() === 'image/webp'
355
+ ? 'webp'
356
+ : 'jpg';
357
+ imageFiles.push(new globalThis.File([blob], `pasted-image-${Date.now()}.${extension}`, { type: imageType }));
358
+ }
359
+ if (imageFiles.length === 0) {
360
+ setUploadError('Clipboard does not currently contain a supported image.');
361
+ return;
362
+ }
363
+ await handleSelectedFiles(imageFiles);
364
+ }
365
+ catch (error) {
366
+ setUploadError(error?.message || 'Failed to read an image from the clipboard.');
367
+ }
368
+ };
369
+ const parseDroppedLinks = (event) => {
370
+ const droppedLinks = new Set();
371
+ const rawUriList = event.dataTransfer.getData('text/uri-list') || '';
372
+ const rawText = event.dataTransfer.getData('text/plain') || '';
373
+ const candidates = `${rawUriList}\n${rawText}`
374
+ .split('\n')
375
+ .map((line) => line.trim())
376
+ .filter((line) => !!line && !line.startsWith('#'));
377
+ for (const candidate of candidates) {
378
+ if (/^file:\/\//i.test(candidate)) {
379
+ try {
380
+ const fileUrl = new URL(candidate);
381
+ const fsPath = decodeURIComponent(fileUrl.pathname || '').trim();
382
+ if (fsPath)
383
+ droppedLinks.add(fsPath);
384
+ }
385
+ catch {
386
+ // Ignore malformed file URL drops
387
+ }
388
+ continue;
389
+ }
390
+ droppedLinks.add(candidate);
391
+ }
392
+ return Array.from(droppedLinks);
393
+ };
394
+ const handleDrop = (event) => {
395
+ event.preventDefault();
396
+ event.stopPropagation();
397
+ setIsDropActive(false);
398
+ setDragDepth(0);
399
+ setUploadError(null);
400
+ setLinkError(null);
401
+ setContextNotice(null);
402
+ if (event.dataTransfer.files && event.dataTransfer.files.length > 0) {
403
+ void handleFilesSelected(event.dataTransfer.files);
404
+ return;
405
+ }
406
+ const droppedLinks = parseDroppedLinks(event);
407
+ if (droppedLinks.length === 0) {
408
+ setLinkError('Drop a file or URL.');
409
+ return;
410
+ }
411
+ const contextKeySet = new Set(contextKeyRef.current);
412
+ let duplicateCount = 0;
413
+ let addedCount = 0;
414
+ let invalidCount = 0;
415
+ droppedLinks.forEach((link) => {
416
+ const result = addLink(link, false, contextKeySet);
417
+ if (result === 'duplicate')
418
+ duplicateCount += 1;
419
+ if (result === 'added')
420
+ addedCount += 1;
421
+ if (result === 'invalid')
422
+ invalidCount += 1;
423
+ });
424
+ const notices = [];
425
+ if (duplicateCount > 0) {
426
+ notices.push(`${duplicateCount} duplicate link${duplicateCount === 1 ? '' : 's'} skipped.`);
427
+ }
428
+ if (invalidCount > 0) {
429
+ notices.push(`${invalidCount} local path${invalidCount === 1 ? '' : 's'} skipped. Upload files to attach them, or drop an http(s) URL to link.`);
430
+ }
431
+ setContextNotice(notices.length > 0 ? notices.join(' ') : (addedCount > 0 ? null : contextNotice));
432
+ contextKeyRef.current = contextKeySet;
433
+ };
434
+ const handleDragEnter = (event) => {
435
+ event.preventDefault();
436
+ event.stopPropagation();
437
+ setDragDepth((depth) => depth + 1);
438
+ setIsDropActive(true);
439
+ };
440
+ const handleDragLeave = (event) => {
441
+ event.preventDefault();
442
+ event.stopPropagation();
443
+ setDragDepth((depth) => {
444
+ const nextDepth = Math.max(0, depth - 1);
445
+ if (nextDepth === 0)
446
+ setIsDropActive(false);
447
+ return nextDepth;
448
+ });
449
+ };
450
+ const handleDragOver = (event) => {
451
+ event.preventDefault();
452
+ event.stopPropagation();
453
+ event.dataTransfer.dropEffect = 'copy';
454
+ };
455
+ const imageFiles = attachments.filter((item) => {
456
+ const path = typeof item === 'string' ? item : item.path;
457
+ return isImagePath(path);
458
+ });
459
+ const documentFiles = attachments.filter((item) => {
460
+ const path = typeof item === 'string' ? item : item.path;
461
+ return !isImagePath(path);
462
+ });
463
+ return (_jsxs("div", { className: styles.specialistSection, children: [_jsxs("div", { className: styles.toggleHeading, onClick: () => setShowContextUpload(!showContextUpload), title: showContextUpload ? 'Hide context documents' : 'Show context documents', children: [_jsxs("label", { className: styles.label, children: ["Context Documents ", attachments.length > 0 && `(${attachments.length})`] }), showContextUpload ? _jsx(ChevronDown, { size: 14 }) : _jsx(ChevronRight, { size: 14 })] }), showContextUpload && (_jsxs(_Fragment, { children: [_jsxs("p", { className: styles.settingsHint, children: ["Upload files into ", ownerTypeLabel, " context storage, or add an external http(s) URL."] }), _jsxs("div", { className: styles.contextUploadPanel, children: [_jsxs("div", { className: styles.contextUploadActions, children: [_jsxs("button", { type: "button", className: styles.secondaryHeaderBtn, onClick: () => inputRef.current?.click(), disabled: uploading, children: [uploading ? _jsx(Loader2, { size: 12, className: styles.spinner }) : _jsx(FileUp, { size: 12 }), uploading ? 'Uploading...' : 'Upload File'] }), _jsxs("button", { type: "button", className: styles.secondaryHeaderBtn, onClick: () => {
464
+ void handlePasteImage();
465
+ }, disabled: uploading, children: [_jsx(Copy, { size: 12 }), "Paste Image from Clipboard"] })] }), _jsx("input", { ref: inputRef, type: "file", accept: ACCEPTED_CONTEXT_FILE_TYPES, multiple: true, className: styles.hiddenInput, onChange: (e) => {
466
+ void handleFilesSelected(e.target.files);
467
+ } }), uploadError && _jsx("div", { className: styles.error, children: uploadError }), _jsxs("div", { className: styles.contextLinkRow, children: [_jsx("input", { type: "text", className: styles.input, placeholder: "Add external URL (https://...)", value: linkValue, onChange: (e) => {
468
+ setLinkValue(e.target.value);
469
+ if (linkError)
470
+ setLinkError(null);
471
+ if (contextNotice)
472
+ setContextNotice(null);
473
+ } }), _jsx("button", { type: "button", className: styles.secondaryHeaderBtn, onClick: () => {
474
+ if (!linkValue.trim()) {
475
+ setLinkError('Enter an http(s) URL to link.');
476
+ return;
477
+ }
478
+ const result = addLink(linkValue, true);
479
+ if (result === 'invalid') {
480
+ setLinkError('Only external http(s) URLs can be linked here. Upload files to attach them.');
481
+ return;
482
+ }
483
+ if (result === 'duplicate') {
484
+ setContextNotice(`Link already exists in ${ownerTypeLabel} context.`);
485
+ }
486
+ else if (result === 'added') {
487
+ setContextNotice(null);
488
+ }
489
+ }, children: "Add URL" })] }), _jsxs("div", { className: `${styles.contextDropzone} ${isDropActive ? styles.contextDropzoneActive : ''}`, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, children: [_jsx(FileUp, { size: 14 }), _jsx("span", { children: "Drop files or URLs here" })] })] }), contextNotice && _jsx("div", { className: styles.contextNotice, children: contextNotice }), linkError && _jsx("div", { className: styles.error, children: linkError }), imageFiles.length > 0 && (_jsx("div", { className: styles.attachmentGrid, children: attachments.map((item, idx) => {
490
+ const path = typeof item === 'string' ? item : item.path;
491
+ if (!isImagePath(path))
492
+ return null;
493
+ const fsPath = typeof item === 'string' ? undefined : item.fsPath;
494
+ const caption = typeof item === 'string' ? '' : item.caption || '';
495
+ const displayName = getAttachmentDisplayName(item);
496
+ const isImage = isImagePath(path);
497
+ const isExternalUrl = /^https?:\/\//i.test(path);
498
+ const canAnnotate = ownerType === 'task'
499
+ && canOpenAnnotatedAttachment(item, { taskId: trimmedOwnerId });
500
+ return (_jsxs("div", { className: styles.attachmentCard, children: [_jsxs("div", { className: styles.attachmentPreviewContainer, children: [isImage ? (_jsx("img", { src: path, alt: caption || `Context file ${idx}`, onClick: () => {
501
+ if (ownerType === 'task'
502
+ && dispatchOpenAnnotatedAttachment(item, {
503
+ taskId: trimmedOwnerId,
504
+ taskReferenceLabel: ownerReferenceLabel,
505
+ }))
506
+ return;
507
+ window.open(path, '_blank');
508
+ }, onError: (e) => {
509
+ e.target.style.display = 'none';
510
+ e.target.parentElement.classList.add(styles.brokenImage);
511
+ } })) : (_jsxs("button", { type: "button", className: styles.contextFileLink, onClick: () => {
512
+ const markdownTarget = ownerType === 'task'
513
+ ? (typeof item === 'string'
514
+ ? { path: item, taskId: trimmedOwnerId }
515
+ : { ...item, taskId: trimmedOwnerId })
516
+ : item;
517
+ if (dispatchOpenMarkdownDocument(markdownTarget, fsPath))
518
+ return;
519
+ window.open(path, '_blank');
520
+ }, title: "Open file", children: [_jsx(FileUp, { size: 16 }), _jsx("span", { children: caption || fsPath || path.split('/').pop() || 'Context file' })] })), _jsxs("div", { className: styles.brokenImagePlaceholder, children: [_jsx(AlertTriangle, { size: 16 }), _jsx("span", { children: "Preview unavailable" })] }), _jsxs("div", { className: styles.attachmentActions, children: [canAnnotate && (_jsx("button", { type: "button", className: styles.attachmentActionBtn, onClick: (e) => {
521
+ e.stopPropagation();
522
+ dispatchOpenAnnotatedAttachment(item, {
523
+ taskId: trimmedOwnerId,
524
+ taskReferenceLabel: ownerReferenceLabel,
525
+ });
526
+ }, title: "Annotate", children: _jsx(PencilLine, { size: 12 }) })), fsPath && (_jsx("button", { type: "button", className: styles.attachmentActionBtn, onClick: (e) => {
527
+ e.stopPropagation();
528
+ navigator.clipboard.writeText(fsPath);
529
+ }, title: `Copy path: ${fsPath}`, children: _jsx(Copy, { size: 12 }) })), !isExternalUrl && (_jsx("button", { type: "button", className: styles.attachmentActionBtn, onClick: (e) => {
530
+ e.stopPropagation();
531
+ window.open(buildDownloadUrl(path, caption || displayName), '_blank');
532
+ }, title: "Download", children: _jsx(Download, { size: 12 }) })), _jsx("button", { type: "button", className: styles.attachmentActionBtn, onClick: (e) => {
533
+ e.stopPropagation();
534
+ onRemoveAttachment(idx);
535
+ }, title: "Delete", children: _jsx(Trash2, { size: 12 }) })] })] }), _jsx("input", { type: "text", className: styles.attachmentCaptionInput, placeholder: "Add a label...", value: caption, onChange: (e) => onUpdateAttachmentCaption(idx, e.target.value) })] }, idx));
536
+ }) })), documentFiles.length > 0 && (_jsx("div", { className: styles.documentAttachmentList, children: attachments.map((item, idx) => {
537
+ const path = typeof item === 'string' ? item : item.path;
538
+ if (isImagePath(path))
539
+ return null;
540
+ const fsPath = typeof item === 'string' ? undefined : item.fsPath;
541
+ const caption = typeof item === 'string' ? '' : item.caption || '';
542
+ const displayName = getAttachmentDisplayName(item);
543
+ const fileType = getAttachmentTypeLabel(item);
544
+ const documentReferenceLabel = typeof item === 'string' ? '' : getDocumentReferenceLabel(item);
545
+ const isExternalUrl = /^https?:\/\//i.test(path);
546
+ return (_jsxs("div", { className: styles.documentAttachmentItem, children: [_jsxs("div", { className: styles.documentAttachmentRow, children: [_jsxs("button", { type: "button", className: styles.documentAttachmentLink, onClick: () => {
547
+ const markdownTarget = ownerType === 'task'
548
+ ? (typeof item === 'string'
549
+ ? { path: item, taskId: trimmedOwnerId }
550
+ : { ...item, taskId: trimmedOwnerId })
551
+ : item;
552
+ if (dispatchOpenMarkdownDocument(markdownTarget, fsPath))
553
+ return;
554
+ window.open(path, '_blank');
555
+ }, title: displayName, children: [_jsxs("span", { className: styles.documentAttachmentMain, children: [_jsx("span", { className: styles.documentAttachmentIcon, "aria-hidden": "true", children: _jsx(File, { size: 13 }) }), _jsxs("span", { className: styles.documentAttachmentText, children: [_jsx("span", { className: styles.documentAttachmentName, children: displayName }), documentReferenceLabel && (_jsx("span", { className: styles.taskIdBadge, children: documentReferenceLabel }))] })] }), _jsx("span", { className: styles.documentAttachmentType, children: fileType })] }), _jsxs("div", { className: styles.documentAttachmentActions, children: [fsPath && (_jsx("button", { type: "button", className: styles.documentAttachmentActionBtn, onClick: () => {
556
+ navigator.clipboard.writeText(fsPath);
557
+ }, title: `Copy path: ${fsPath}`, children: _jsx(Copy, { size: 12 }) })), !isExternalUrl && (_jsx("button", { type: "button", className: styles.documentAttachmentActionBtn, onClick: () => {
558
+ window.open(buildDownloadUrl(path, caption || displayName), '_blank');
559
+ }, title: "Download", children: _jsx(Download, { size: 12 }) })), _jsx("button", { type: "button", className: styles.documentAttachmentActionBtn, onClick: () => onRemoveAttachment(idx), title: "Delete", children: _jsx(Trash2, { size: 12 }) })] })] }), _jsx("input", { type: "text", className: styles.documentAttachmentCaptionInput, placeholder: "Add a label...", value: caption, onChange: (e) => onUpdateAttachmentCaption(idx, e.target.value) })] }, idx));
560
+ }) }))] }))] }));
561
+ }
@@ -1,5 +1,18 @@
1
+ import React from 'react';
2
+ type AiProfileSeatUsage = {
3
+ used: number;
4
+ limit: number | null;
5
+ remaining: number | null;
6
+ };
1
7
  interface AgentsModuleProps {
2
8
  workspaceId: string;
9
+ cloudAuthConfigured?: boolean;
10
+ authSessionResolved?: boolean;
11
+ isAuthenticated?: boolean;
12
+ cloudAiProfileSeatUsage?: AiProfileSeatUsage | null;
13
+ agentTrayOpen?: boolean;
14
+ onCloseAgentTray?: () => void;
15
+ mcpSettingsNode?: React.ReactNode;
3
16
  }
4
- export declare function AgentsModule({ workspaceId }: AgentsModuleProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function AgentsModule({ workspaceId, cloudAuthConfigured, authSessionResolved, isAuthenticated, cloudAiProfileSeatUsage, agentTrayOpen, onCloseAgentTray, mcpSettingsNode, }: AgentsModuleProps): import("react/jsx-runtime").JSX.Element;
5
18
  export {};