@taskforcehq/taskforce 0.3.305 → 0.3.306

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 (337) hide show
  1. package/dist/Taskforce.module.css +295 -89
  2. package/dist/TaskforceCore.js +215 -43
  3. package/dist/TaskforceCore.test.js +433 -28
  4. package/dist/assets/fonts/CourierPrime-Bold.woff2 +0 -0
  5. package/dist/assets/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  6. package/dist/assets/fonts/CourierPrime-Italic.woff2 +0 -0
  7. package/dist/assets/fonts/CourierPrime-Regular.woff2 +0 -0
  8. package/dist/assets/fonts/Noir_medium.woff2 +0 -0
  9. package/dist/assets/fonts/Noir_regular.woff2 +0 -0
  10. package/dist/assets/fonts/RussoOne-Regular.woff2 +0 -0
  11. package/dist/assets/fonts/SpecialElite-Regular.woff2 +0 -0
  12. package/dist/compat/workspaceSyncCompat.js +46 -2
  13. package/dist/compat/workspaceSyncCompat.test.js +38 -1
  14. package/dist/components/context/ContextAttachmentManager.d.ts +14 -0
  15. package/dist/components/context/ContextAttachmentManager.js +549 -0
  16. package/dist/components/features/AgentsModule.d.ts +10 -1
  17. package/dist/components/features/AgentsModule.js +260 -15
  18. package/dist/components/features/AgentsModule.test.js +255 -5
  19. package/dist/components/features/DocumentViewer.d.ts +5 -1
  20. package/dist/components/features/DocumentViewer.js +60 -3
  21. package/dist/components/features/DocumentWorkspace.js +1 -1
  22. package/dist/components/features/DocumentWorkspace.test.js +33 -0
  23. package/dist/components/features/documentWorkspaceModel.d.ts +1 -1
  24. package/dist/components/task/TaskCard.js +19 -28
  25. package/dist/components/task/TaskCard.test.js +38 -3
  26. package/dist/components/task/TaskContextUpload.js +4 -526
  27. package/dist/components/task/TaskForm.js +85 -90
  28. package/dist/components/task/TaskForm.test.js +110 -8
  29. package/dist/components/task/TaskKanban.d.ts +2 -1
  30. package/dist/components/task/TaskKanban.js +94 -13
  31. package/dist/components/task/TaskKanban.test.js +36 -0
  32. package/dist/components/ui/EditableAvatarButton.d.ts +18 -0
  33. package/dist/components/ui/EditableAvatarButton.js +18 -0
  34. package/dist/components/views/PlanComparisonPage.d.ts +9 -1
  35. package/dist/components/views/PlanComparisonPage.js +70 -14
  36. package/dist/components/views/PlanComparisonPage.test.js +238 -0
  37. package/dist/components/views/PlansPage.js +127 -36
  38. package/dist/components/views/PlansPage.test.js +294 -12
  39. package/dist/components/views/StandaloneLayout.js +283 -533
  40. package/dist/components/views/panels/PlanningDrawer.d.ts +8 -1
  41. package/dist/components/views/panels/PlanningDrawer.js +18 -11
  42. package/dist/components/views/panels/PlanningDrawer.test.d.ts +1 -0
  43. package/dist/components/views/panels/PlanningDrawer.test.js +141 -0
  44. package/dist/components/views/planningScope.d.ts +20 -0
  45. package/dist/components/views/planningScope.js +25 -0
  46. package/dist/components/views/planningScope.test.d.ts +1 -0
  47. package/dist/components/views/planningScope.test.js +60 -0
  48. package/dist/components/views/standalone/modals/AccountHubModal.d.ts +26 -1
  49. package/dist/components/views/standalone/modals/AccountHubModal.js +76 -2
  50. package/dist/components/views/standalone/modals/AccountHubModal.test.js +20 -3
  51. package/dist/components/views/standalone/modals/AvatarImageManagerModal.d.ts +20 -0
  52. package/dist/components/views/standalone/modals/AvatarImageManagerModal.js +127 -0
  53. package/dist/components/views/standalone/modals/EditProfileModal.d.ts +2 -9
  54. package/dist/components/views/standalone/modals/EditProfileModal.js +3 -2
  55. package/dist/components/views/standalone/modals/SyncEnableWarningModal.d.ts +9 -0
  56. package/dist/components/views/standalone/modals/SyncEnableWarningModal.js +6 -0
  57. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.d.ts +1 -0
  58. package/dist/components/views/standalone/modals/SyncEnableWarningModal.test.js +24 -0
  59. package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +2 -1
  60. package/dist/components/views/standalone/modals/SyncStatusModal.js +2 -2
  61. package/dist/core/AiProfileService.d.ts +39 -2
  62. package/dist/core/AiProfileService.js +639 -73
  63. package/dist/core/AiProfileService.test.js +19 -1
  64. package/dist/core/AiProfiles.test.js +566 -7
  65. package/dist/core/AttachmentLinkService.js +57 -15
  66. package/dist/core/AuthIdentityService.d.ts +107 -0
  67. package/dist/core/AuthIdentityService.js +284 -0
  68. package/dist/core/AuthTokenService.d.ts +4 -0
  69. package/dist/core/AuthTokenService.js +34 -6
  70. package/dist/core/AuthTokenService.test.js +3 -3
  71. package/dist/core/EntitlementsPolicy.test.js +2 -2
  72. package/dist/core/GlobalSettingsService.js +115 -6
  73. package/dist/core/PlanEntitlementService.d.ts +23 -2
  74. package/dist/core/PlanEntitlementService.js +343 -57
  75. package/dist/core/PlanFeatureCatalog.test.d.ts +1 -0
  76. package/dist/core/PlanFeatureCatalog.test.js +84 -0
  77. package/dist/core/PlanVersionPolicy.test.js +35 -2
  78. package/dist/core/PlanningEntities.test.js +52 -0
  79. package/dist/core/SignupMonetizationSettings.test.js +199 -27
  80. package/dist/core/SyncReconciliationService.js +2 -65
  81. package/dist/core/SystemAdmin.test.js +42 -42
  82. package/dist/core/TaskAttachmentsCanonical.test.js +51 -1
  83. package/dist/core/Taskforce.d.ts +225 -14
  84. package/dist/core/Taskforce.js +765 -192
  85. package/dist/core/Taskforce.listTasksSlim.test.d.ts +1 -0
  86. package/dist/core/Taskforce.listTasksSlim.test.js +91 -0
  87. package/dist/core/UserProfileAvatarDrafts.test.js +30 -3
  88. package/dist/core/WorkspaceLifecycleService.js +0 -5
  89. package/dist/core/WorkspacePermissions.test.js +25 -1
  90. package/dist/core/WorkspacePlanMode.test.js +117 -16
  91. package/dist/core/shared.d.ts +1 -1
  92. package/dist/core/shared.js +5 -1
  93. package/dist/core/types.d.ts +68 -2
  94. package/dist/hooks/auth/useTaskforceAuthBootstrap.js +26 -1
  95. package/dist/hooks/sync/bootstrap.js +2 -0
  96. package/dist/hooks/sync/controlPlane.d.ts +37 -0
  97. package/dist/hooks/sync/controlPlane.js +78 -0
  98. package/dist/hooks/sync/controlPlane.test.d.ts +1 -0
  99. package/dist/hooks/sync/controlPlane.test.js +121 -0
  100. package/dist/hooks/sync/lifecyclePolicy.d.ts +45 -0
  101. package/dist/hooks/sync/lifecyclePolicy.js +93 -0
  102. package/dist/hooks/sync/lifecyclePolicy.test.d.ts +1 -0
  103. package/dist/hooks/sync/lifecyclePolicy.test.js +124 -0
  104. package/dist/hooks/sync/orchestratorShared.d.ts +10 -1
  105. package/dist/hooks/sync/orchestratorShared.js +68 -47
  106. package/dist/hooks/sync/orchestratorShared.test.js +50 -1
  107. package/dist/hooks/sync/pullLifecycle.d.ts +31 -0
  108. package/dist/hooks/sync/pullLifecycle.js +24 -0
  109. package/dist/hooks/sync/pullLifecycle.test.d.ts +1 -0
  110. package/dist/hooks/sync/pullLifecycle.test.js +80 -0
  111. package/dist/hooks/sync/recovery.d.ts +16 -2
  112. package/dist/hooks/sync/recovery.js +171 -53
  113. package/dist/hooks/sync/recovery.test.d.ts +1 -0
  114. package/dist/hooks/sync/recovery.test.js +292 -0
  115. package/dist/hooks/sync/transfers.d.ts +15 -3
  116. package/dist/hooks/sync/transfers.js +179 -62
  117. package/dist/hooks/sync/transfers.test.d.ts +1 -0
  118. package/dist/hooks/sync/transfers.test.js +396 -0
  119. package/dist/hooks/sync/useRecentSyncEvents.d.ts +21 -0
  120. package/dist/hooks/sync/useRecentSyncEvents.js +92 -0
  121. package/dist/hooks/sync/useRecentSyncEvents.test.d.ts +1 -0
  122. package/dist/hooks/sync/useRecentSyncEvents.test.js +124 -0
  123. package/dist/hooks/sync/useSyncStatusActions.d.ts +30 -0
  124. package/dist/hooks/sync/useSyncStatusActions.js +88 -0
  125. package/dist/hooks/sync/useSyncStatusActions.test.d.ts +1 -0
  126. package/dist/hooks/sync/useSyncStatusActions.test.js +133 -0
  127. package/dist/hooks/sync/useSyncStatusControls.d.ts +25 -0
  128. package/dist/hooks/sync/useSyncStatusControls.js +60 -0
  129. package/dist/hooks/sync/useSyncStatusControls.test.d.ts +1 -0
  130. package/dist/hooks/sync/useSyncStatusControls.test.js +88 -0
  131. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +12 -0
  132. package/dist/hooks/useSyncOrchestrator.d.ts +9 -2
  133. package/dist/hooks/useSyncOrchestrator.js +359 -178
  134. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +407 -0
  135. package/dist/hooks/useTaskData.js +8 -3
  136. package/dist/hooks/useTaskData.test.js +45 -0
  137. package/dist/hooks/useTaskforce.d.ts +60 -2
  138. package/dist/hooks/useTaskforce.js +549 -240
  139. package/dist/hooks/useTaskforce.runtime-routing.test.d.ts +1 -0
  140. package/dist/hooks/useTaskforce.runtime-routing.test.js +152 -0
  141. package/dist/hooks/useTaskforce.sync-behavior.test.js +2380 -212
  142. package/dist/hooks/useWorkspaceSyncController.d.ts +1 -0
  143. package/dist/hooks/useWorkspaceSyncController.js +6 -1
  144. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.d.ts +16 -0
  145. package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +316 -35
  146. package/dist/localization/locales/en-US.d.ts +0 -1
  147. package/dist/localization/locales/en-US.js +0 -1
  148. package/dist/localization/locales/es-419.js +0 -1
  149. package/dist/localization/locales/pt-BR.js +0 -1
  150. package/dist/mcp/documentAssetRegistrar.js +3 -3
  151. package/dist/mcp/runtime.d.ts +2 -0
  152. package/dist/mcp/runtime.js +131 -64
  153. package/dist/mcp/runtime.test.js +291 -12
  154. package/dist/migrations/taskSchemaMigrations.d.ts +1 -1
  155. package/dist/migrations/taskSchemaMigrations.js +171 -61
  156. package/dist/migrations/taskSchemaMigrations.test.js +15 -0
  157. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  158. package/dist/resources/templates/workflows/collaborate.yaml +1 -1
  159. package/dist/resources/templates/workflows/evaluate.yaml +2 -2
  160. package/dist/resources/templates/workflows/plan.yaml +1 -1
  161. package/dist/resources/templates/workflows/review.yaml +2 -2
  162. package/dist/server/annotatedAttachmentsRoutes.test.js +3 -3
  163. package/dist/server/auth/providers/apple.d.ts +33 -0
  164. package/dist/server/auth/providers/apple.js +82 -0
  165. package/dist/server/auth/providers/appleClientSecret.d.ts +37 -0
  166. package/dist/server/auth/providers/appleClientSecret.js +65 -0
  167. package/dist/server/auth/providers/github.d.ts +26 -0
  168. package/dist/server/auth/providers/github.js +86 -0
  169. package/dist/server/auth/providers/google.d.ts +21 -0
  170. package/dist/server/auth/providers/google.js +56 -0
  171. package/dist/server/auth/providers/types.d.ts +21 -0
  172. package/dist/server/auth/providers/types.js +1 -0
  173. package/dist/server/auth.d.ts +2 -0
  174. package/dist/server/auth.js +6 -3
  175. package/dist/server/documentReviewRoutes.test.js +36 -3
  176. package/dist/server/index.cookieProxy.test.js +1 -0
  177. package/dist/server/index.d.ts +12 -0
  178. package/dist/server/index.js +120 -9
  179. package/dist/server/index.rateLimit.test.js +3 -0
  180. package/dist/server/index.test.js +106 -3
  181. package/dist/server/routes/admin.d.ts +3 -0
  182. package/dist/server/routes/admin.js +272 -19
  183. package/dist/server/routes/auth.d.ts +15 -2
  184. package/dist/server/routes/auth.js +994 -57
  185. package/dist/server/routes/authSupport.d.ts +1 -1
  186. package/dist/server/routes/authSupport.js +1 -1
  187. package/dist/server/routes/billing.js +361 -35
  188. package/dist/server/routes/billing.test.js +592 -12
  189. package/dist/server/routes/documents.d.ts +1 -0
  190. package/dist/server/routes/documents.js +172 -70
  191. package/dist/server/routes/shared.d.ts +28 -2
  192. package/dist/server/routes/shared.js +69 -4
  193. package/dist/server/routes/sync.integration.test.js +437 -39
  194. package/dist/server/routes/sync.js +61 -605
  195. package/dist/server/routes/syncAuxRoutes.d.ts +15 -0
  196. package/dist/server/routes/syncAuxRoutes.js +91 -0
  197. package/dist/server/routes/syncAuxRoutes.test.d.ts +1 -0
  198. package/dist/server/routes/syncAuxRoutes.test.js +158 -0
  199. package/dist/server/routes/syncPullApplyRoutes.d.ts +36 -0
  200. package/dist/server/routes/syncPullApplyRoutes.js +204 -0
  201. package/dist/server/routes/syncPushRoutes.d.ts +24 -0
  202. package/dist/server/routes/syncPushRoutes.js +212 -0
  203. package/dist/server/routes/syncRouteGuards.d.ts +36 -0
  204. package/dist/server/routes/syncRouteGuards.js +67 -0
  205. package/dist/server/routes/syncRouteGuards.test.d.ts +1 -0
  206. package/dist/server/routes/syncRouteGuards.test.js +94 -0
  207. package/dist/server/routes/syncRouteTypes.d.ts +13 -0
  208. package/dist/server/routes/syncRouteTypes.js +1 -0
  209. package/dist/server/routes/syncSnapshotRoutes.d.ts +66 -0
  210. package/dist/server/routes/syncSnapshotRoutes.js +180 -0
  211. package/dist/server/routes/tasks.js +43 -1
  212. package/dist/server/routes/workspaces.js +36 -5
  213. package/dist/server/routes.js +60 -3
  214. package/dist/server/routes.test.js +1824 -171
  215. package/dist/services/workflowExportSnapshots.test.js +2 -0
  216. package/dist/shared/aiProfileSeatScope.d.ts +5 -0
  217. package/dist/shared/aiProfileSeatScope.js +21 -0
  218. package/dist/shared/passwordPolicy.d.ts +13 -0
  219. package/dist/shared/passwordPolicy.js +84 -0
  220. package/dist/shared/passwordPolicy.test.d.ts +1 -0
  221. package/dist/shared/passwordPolicy.test.js +34 -0
  222. package/dist/storage/workspaceAssetStore.d.ts +15 -3
  223. package/dist/storage/workspaceAssetStore.js +132 -44
  224. package/dist/storage/workspaceAssetStore.test.js +93 -6
  225. package/dist/styles/fonts.css +70 -0
  226. package/dist/sync/collaborationSyncPayload.d.ts +6 -1
  227. package/dist/sync/collaborationSyncPayload.js +17 -11
  228. package/dist/sync/collaborationSyncPayload.test.js +13 -1
  229. package/dist/sync/contentSyncState.d.ts +4 -8
  230. package/dist/sync/contentSyncState.js +17 -70
  231. package/dist/sync/syncApplyHandlers.d.ts +7 -0
  232. package/dist/sync/syncApplyHandlers.js +28 -13
  233. package/dist/sync/syncApplyHandlers.test.js +70 -3
  234. package/dist/sync/syncFieldSemantics.d.ts +12 -0
  235. package/dist/sync/syncFieldSemantics.js +55 -0
  236. package/dist/sync/syncResourceAdapters.d.ts +44 -0
  237. package/dist/sync/syncResourceAdapters.js +77 -0
  238. package/dist/sync/syncService.d.ts +5 -0
  239. package/dist/sync/syncService.js +52 -0
  240. package/dist/sync/syncService.test.js +57 -3
  241. package/dist/sync/taskSyncChangeKey.d.ts +2 -0
  242. package/dist/sync/taskSyncChangeKey.js +143 -0
  243. package/dist/sync/taskSyncPayload.js +3 -8
  244. package/dist/sync/workspacePullFeed.js +4 -3
  245. package/dist/sync/workspacePullFeed.test.js +43 -0
  246. package/dist/sync/workspaceRepair.js +5 -2
  247. package/dist/sync/workspaceSyncModel.d.ts +45 -0
  248. package/dist/sync/workspaceSyncModel.js +183 -28
  249. package/dist/sync/workspaceSyncModel.test.js +291 -12
  250. package/dist/sync/workspaceSyncState.d.ts +17 -0
  251. package/dist/sync/workspaceSyncState.js +2 -1
  252. package/dist/sync/workspaceSyncSurface.js +3 -8
  253. package/dist/types.d.ts +17 -0
  254. package/dist/ui/assets/AgentsModule-DrLawwNl.js +1 -0
  255. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BG6P_GVW.js → AnnotatedAttachmentWorkspace-Z9_whf7F.js} +1 -1
  256. package/dist/ui/assets/CourierPrime-Bold-BuLj_dpw.woff2 +0 -0
  257. package/dist/ui/assets/CourierPrime-BoldItalic-BrK2pUkZ.woff2 +0 -0
  258. package/dist/ui/assets/CourierPrime-Italic-DFUZK5Ey.woff2 +0 -0
  259. package/dist/ui/assets/CourierPrime-Regular-BsKphzVf.woff2 +0 -0
  260. package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +252 -0
  261. package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +1 -0
  262. package/dist/ui/assets/{InitiativesModule-Dhm7M8e7.js → InitiativesModule-9E6ParrY.js} +1 -1
  263. package/dist/ui/assets/Noir_medium-bxQwKGzB.woff2 +0 -0
  264. package/dist/ui/assets/Noir_regular-ojf2kxlG.woff2 +0 -0
  265. package/dist/ui/assets/PlansPage-CvfnMiWq.css +1 -0
  266. package/dist/ui/assets/PlansPage-DRXscYxH.js +1 -0
  267. package/dist/ui/assets/RussoOne-Regular-Cu_qq_qC.woff2 +0 -0
  268. package/dist/ui/assets/SpecialElite-Regular-Di6gSvAS.woff2 +0 -0
  269. package/dist/ui/assets/{TaskSettings-ln0aF7xc.js → TaskSettings-DZX4jk7e.js} +1 -1
  270. package/dist/ui/assets/{WorkflowsModule-BcS4afRn.js → WorkflowsModule-BA7jcEpH.js} +1 -1
  271. package/dist/ui/assets/index-9eT8e0Lu.css +1 -0
  272. package/dist/ui/assets/index-C6k75jr8.js +6 -0
  273. package/dist/ui/assets/{vendor-icons-BSUaRwF8.js → vendor-icons-DuEd_65c.js} +1 -1
  274. package/dist/ui/fonts/CourierPrime-Bold.ttf +0 -0
  275. package/dist/ui/fonts/CourierPrime-Bold.woff2 +0 -0
  276. package/dist/ui/fonts/CourierPrime-BoldItalic.ttf +0 -0
  277. package/dist/ui/fonts/CourierPrime-BoldItalic.woff2 +0 -0
  278. package/dist/ui/fonts/CourierPrime-Italic.ttf +0 -0
  279. package/dist/ui/fonts/CourierPrime-Italic.woff2 +0 -0
  280. package/dist/ui/fonts/CourierPrime-Regular.ttf +0 -0
  281. package/dist/ui/fonts/CourierPrime-Regular.woff2 +0 -0
  282. package/dist/ui/fonts/Noir_medium.otf +0 -0
  283. package/dist/ui/fonts/Noir_medium.woff2 +0 -0
  284. package/dist/ui/fonts/Noir_regular.otf +0 -0
  285. package/dist/ui/fonts/Noir_regular.woff2 +0 -0
  286. package/dist/ui/fonts/RussoOne-Regular.woff2 +0 -0
  287. package/dist/ui/fonts/SpecialElite-Regular.ttf +0 -0
  288. package/dist/ui/fonts/SpecialElite-Regular.woff2 +0 -0
  289. package/dist/ui/index.html +3 -3
  290. package/dist/utils/accountProfileSummaryCache.d.ts +5 -0
  291. package/dist/utils/assignees.d.ts +2 -0
  292. package/dist/utils/assignees.js +2 -0
  293. package/dist/utils/avatarUpload.d.ts +27 -0
  294. package/dist/utils/avatarUpload.js +132 -0
  295. package/dist/utils/avatarUpload.test.d.ts +1 -0
  296. package/dist/utils/avatarUpload.test.js +40 -0
  297. package/dist/utils/bootstrapTrace.d.ts +7 -0
  298. package/dist/utils/bootstrapTrace.js +29 -0
  299. package/dist/utils/commercialLifecyclePresentation.js +3 -0
  300. package/dist/utils/contextAssetEvents.d.ts +2 -0
  301. package/dist/utils/syncEventDetails.d.ts +3 -0
  302. package/dist/utils/syncEventDetails.js +64 -0
  303. package/dist/utils/syncEventDetails.test.d.ts +1 -0
  304. package/dist/utils/syncEventDetails.test.js +23 -0
  305. package/dist/utils/syncEventPresentation.d.ts +15 -0
  306. package/dist/utils/syncEventPresentation.js +129 -0
  307. package/dist/utils/syncEventPresentation.test.d.ts +1 -0
  308. package/dist/utils/syncEventPresentation.test.js +64 -0
  309. package/dist/utils/syncStatusPresentation.d.ts +72 -0
  310. package/dist/utils/syncStatusPresentation.js +217 -0
  311. package/dist/utils/syncStatusPresentation.test.d.ts +1 -0
  312. package/dist/utils/syncStatusPresentation.test.js +164 -0
  313. package/dist/utils/taskActivity.d.ts +2 -0
  314. package/dist/utils/taskActivity.js +228 -22
  315. package/dist/utils/taskActivity.test.js +119 -8
  316. package/dist/utils/workspaceSyncPresentation.d.ts +4 -0
  317. package/dist/utils/workspaceSyncPresentation.js +68 -2
  318. package/dist/utils/workspaceSyncPresentation.test.js +36 -1
  319. package/package.json +3 -2
  320. package/scripts/export-sqlite-to-postgres.mjs +7 -9
  321. package/scripts/run-e2e-realtime.sh +17 -3
  322. package/scripts/run-smoke.sh +17 -5
  323. package/scripts/run-soak.sh +17 -5
  324. package/src/resources/templates/workflow-sources/workflowDocs.mjs +6 -6
  325. package/src/resources/templates/workflows/collaborate.yaml +1 -1
  326. package/src/resources/templates/workflows/evaluate.yaml +2 -2
  327. package/src/resources/templates/workflows/plan.yaml +1 -1
  328. package/src/resources/templates/workflows/review.yaml +2 -2
  329. package/dist/ui/assets/AgentsModule-N2MnQBZk.js +0 -1
  330. package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +0 -1
  331. package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +0 -252
  332. package/dist/ui/assets/PlansPage-C2dd2n1X.css +0 -1
  333. package/dist/ui/assets/PlansPage-Cq0zXj3I.js +0 -1
  334. package/dist/ui/assets/RussoOne-Regular-C3BxZIj7.ttf +0 -0
  335. package/dist/ui/assets/index-C2-OXZV7.css +0 -1
  336. package/dist/ui/assets/index-DcSI5F86.js +0 -6
  337. package/scripts/migrate-planning-model.ts +0 -233
@@ -323,6 +323,7 @@ describe('Taskforce MCP tool descriptions', () => {
323
323
  const getTask = getTool(result, 'get_task');
324
324
  const getPaths = getTool(result, 'get_paths');
325
325
  const searchImages = getTool(result, 'search_images');
326
+ const getImage = getTool(result, 'get_image');
326
327
  const getDocument = getTool(result, 'get_document');
327
328
  const searchDocuments = getTool(result, 'search_documents');
328
329
  const listAnnotatedAttachmentSessions = getTool(result, 'get_annotated_attachment_sessions');
@@ -341,10 +342,13 @@ describe('Taskforce MCP tool descriptions', () => {
341
342
  expect(getTask.description).toContain('Do not use this for image references like I-123 or document references like D-123.');
342
343
  expect(getPaths.description).toContain('Get project and Taskforce storage paths.');
343
344
  expect(searchImages.description).toContain('I-123 reference');
345
+ expect(getImage.description).toContain('placement, or visual correction feedback');
344
346
  expect(getDocument.description).toContain('D-123');
345
347
  expect(searchDocuments.description).toContain('D-123 reference');
346
348
  expect(listAnnotatedAttachmentSessions.description).toContain('saved annotation sessions');
349
+ expect(listAnnotatedAttachmentSessions.description).toContain('inspect the saved session payload next');
347
350
  expect(readAnnotatedAttachmentPayload.description).toContain('derived crop hints');
351
+ expect(readAnnotatedAttachmentPayload.description).toContain('authoritative instruction source');
348
352
  expect(createAnnotatedAttachmentSession.description).toContain('before adding markers');
349
353
  expect(deleteAnnotatedAttachmentSession.description).toContain('rather than deleting markers one by one');
350
354
  expect(reviewImage.description).toContain('first-pass visual review');
@@ -400,6 +404,7 @@ describe('Taskforce MCP tool descriptions', () => {
400
404
  expect(getTask.description).toContain('Do not use this for image references like I-123 or document references like D-123.');
401
405
  expect(searchImages.description).toContain('get_image');
402
406
  expect(getImage.description).toContain('Use this first when the user references an image');
407
+ expect(getImage.description).toContain('read the saved annotation payload before making changes');
403
408
  expect(searchDocuments.description).toContain('get_document');
404
409
  expect(searchDocuments.description).toContain('read_document_content');
405
410
  expect(getDocument.description).toContain('Use this first when the user references a document');
@@ -733,7 +738,7 @@ describe('Taskforce MCP tool descriptions', () => {
733
738
  fs.rmSync(projectRoot, { recursive: true, force: true });
734
739
  }
735
740
  });
736
- it('updates and persists metadata when cloud auto-bind reuses an existing exact-match profile', async () => {
741
+ it('creates a separate cloud profile and persists metadata when a same-name local profile already exists', async () => {
737
742
  const projectRoot = createProjectRoot();
738
743
  try {
739
744
  const initial = parseToolJson(await callTool(projectRoot, 'local', 'resolve_profile', {
@@ -754,29 +759,36 @@ describe('Taskforce MCP tool descriptions', () => {
754
759
  authAiProfileSurfaceType: 'coding_tool'
755
760
  }));
756
761
  expect(currentProfile.profile).toEqual(expect.objectContaining({
757
- id: initial.profile.id,
758
762
  name: 'Automation Codex',
759
763
  description: 'OpenAI Codex coding agent connected through MCP.',
760
764
  role: 'Coding Agent',
761
765
  provider: 'OpenAI',
762
766
  model: 'Codex',
763
- surfaceType: 'coding_tool'
767
+ surfaceType: 'coding_tool',
768
+ seatScope: 'cloud_metered'
764
769
  }));
770
+ expect(currentProfile.profile.id).not.toBe(initial.profile.id);
765
771
  const reloadedCore = new TaskforceCore({
766
772
  projectRoot,
767
773
  storagePath: path.join(projectRoot, '.taskforce')
768
774
  });
769
- expect(reloadedCore.listAiProfiles('workspace-1')).toEqual([
775
+ expect(reloadedCore.listAiProfiles('workspace-1')).toEqual(expect.arrayContaining([
770
776
  expect.objectContaining({
771
777
  id: initial.profile.id,
772
778
  name: 'Automation Codex',
779
+ seatScope: 'local_unmetered'
780
+ }),
781
+ expect.objectContaining({
782
+ id: currentProfile.profile.id,
783
+ name: 'Automation Codex',
773
784
  description: 'OpenAI Codex coding agent connected through MCP.',
774
785
  role: 'Coding Agent',
775
786
  provider: 'OpenAI',
776
787
  model: 'Codex',
777
- surfaceType: 'coding_tool'
788
+ surfaceType: 'coding_tool',
789
+ seatScope: 'cloud_metered'
778
790
  })
779
- ]);
791
+ ]));
780
792
  reloadedCore.close();
781
793
  }
782
794
  finally {
@@ -809,9 +821,12 @@ describe('Taskforce MCP tool descriptions', () => {
809
821
  it('allows mutating cloud MCP tools when the connection is configured with an AI profile token', async () => {
810
822
  const projectRoot = createProjectRoot();
811
823
  try {
812
- const resolved = parseToolJson(await callTool(projectRoot, 'local', 'resolve_profile', {
824
+ const resolved = parseToolJson(await callTool(projectRoot, 'cloud', 'resolve_profile', {
813
825
  name: 'Automation Codex'
814
- }, { resolveProfile: false }));
826
+ }, {
827
+ workspaceId: 'workspace-1',
828
+ resolveProfile: false
829
+ }));
815
830
  const created = parseToolJson(await callTool(projectRoot, 'cloud', 'create_task', {
816
831
  title: 'Configured token write'
817
832
  }, {
@@ -866,6 +881,100 @@ describe('Taskforce MCP tool descriptions', () => {
866
881
  fs.rmSync(projectRoot, { recursive: true, force: true });
867
882
  }
868
883
  });
884
+ it('blocks cloud auto-bind when the configured AI profile has been retired by name until resolve_profile explicitly reactivates it', async () => {
885
+ const projectRoot = createProjectRoot();
886
+ try {
887
+ const core = new TaskforceCore({
888
+ projectRoot,
889
+ storagePath: path.join(projectRoot, '.taskforce')
890
+ });
891
+ const resolved = core.resolveAiProfile({
892
+ workspaceId: 'workspace-1',
893
+ name: 'Automation Codex',
894
+ }, { trustedSeatScope: 'cloud_metered' });
895
+ core.archiveAiProfile({
896
+ workspaceId: 'workspace-1',
897
+ profileId: resolved.profile.id,
898
+ archivedBy: 'owner-1',
899
+ reason: 'manual_archive'
900
+ });
901
+ core.close();
902
+ const blocked = await callTool(projectRoot, 'cloud', 'create_task', {
903
+ title: 'Should stay retired'
904
+ }, {
905
+ workspaceId: 'workspace-1',
906
+ resolveProfile: false,
907
+ authAiProfileName: 'Automation Codex'
908
+ });
909
+ expect(blocked.isError).toBe(true);
910
+ const blockedPayload = parseToolJson(blocked);
911
+ expect(blockedPayload.code).toBe('AI_PROFILE_RETIRED');
912
+ expect(blockedPayload.error).toContain('has been retired from this workspace');
913
+ expect(blockedPayload.nextTool).toBe('resolve_profile');
914
+ const reactivated = parseToolJson(await callTool(projectRoot, 'cloud', 'resolve_profile', {
915
+ name: 'Automation Codex',
916
+ surfaceType: 'agent'
917
+ }, {
918
+ workspaceId: 'workspace-1',
919
+ resolveProfile: false,
920
+ authAiProfileName: 'Automation Codex'
921
+ }));
922
+ expect(reactivated.created).toBe(false);
923
+ expect(reactivated.profile.id).toBe(resolved.profile.id);
924
+ expect(reactivated.profile.archivedAt ?? null).toBeNull();
925
+ const created = parseToolJson(await callTool(projectRoot, 'cloud', 'create_task', {
926
+ title: 'Reactivated automation write'
927
+ }, {
928
+ workspaceId: 'workspace-1',
929
+ resolveProfile: false,
930
+ authAiProfileName: 'Automation Codex'
931
+ }));
932
+ expect(created.title).toBe('Reactivated automation write');
933
+ expect(created.createdBy).toBe(resolved.profile.id);
934
+ }
935
+ finally {
936
+ fs.rmSync(projectRoot, { recursive: true, force: true });
937
+ }
938
+ });
939
+ it('blocks cloud auto-bind when the configured AI profile token belongs to a retired profile', async () => {
940
+ const projectRoot = createProjectRoot();
941
+ try {
942
+ const core = new TaskforceCore({
943
+ projectRoot,
944
+ storagePath: path.join(projectRoot, '.taskforce')
945
+ });
946
+ const resolved = core.resolveAiProfile({
947
+ workspaceId: 'workspace-1',
948
+ name: 'Automation Codex',
949
+ }, { trustedSeatScope: 'cloud_metered' });
950
+ core.archiveAiProfile({
951
+ workspaceId: 'workspace-1',
952
+ profileId: resolved.profile.id,
953
+ archivedBy: 'owner-1',
954
+ reason: 'manual_archive'
955
+ });
956
+ core.close();
957
+ const blocked = await callTool(projectRoot, 'cloud', 'create_task', {
958
+ title: 'Token should stay retired'
959
+ }, {
960
+ workspaceId: 'workspace-1',
961
+ resolveProfile: false,
962
+ authAiProfileToken: resolved.profile.profileToken,
963
+ authAiProfileName: 'Automation Codex'
964
+ });
965
+ expect(blocked.isError).toBe(true);
966
+ const blockedPayload = parseToolJson(blocked);
967
+ expect(blockedPayload.code).toBe('AI_PROFILE_RETIRED');
968
+ expect(blockedPayload.details).toEqual(expect.objectContaining({
969
+ profileId: resolved.profile.id,
970
+ profileToken: resolved.profile.profileToken,
971
+ archivedReason: 'manual_archive'
972
+ }));
973
+ }
974
+ finally {
975
+ fs.rmSync(projectRoot, { recursive: true, force: true });
976
+ }
977
+ });
869
978
  it('blocks cloud auto-bind when the workspace has no remaining ai profile seats', async () => {
870
979
  const projectRoot = createProjectRoot();
871
980
  try {
@@ -895,8 +1004,8 @@ describe('Taskforce MCP tool descriptions', () => {
895
1004
  });
896
1005
  core.resolveAiProfile({
897
1006
  workspaceId: 'workspace-1',
898
- name: 'Existing Automation Bot'
899
- });
1007
+ name: 'Existing Automation Bot',
1008
+ }, { trustedSeatScope: 'cloud_metered' });
900
1009
  core.close();
901
1010
  const result = await callTool(projectRoot, 'cloud', 'create_task', {
902
1011
  title: 'Blocked automation write'
@@ -1009,8 +1118,8 @@ describe('Taskforce MCP tool descriptions', () => {
1009
1118
  });
1010
1119
  core.resolveAiProfile({
1011
1120
  workspaceId: 'workspace-1',
1012
- name: 'Existing Automation Bot'
1013
- });
1121
+ name: 'Existing Automation Bot',
1122
+ }, { trustedSeatScope: 'cloud_metered' });
1014
1123
  core.close();
1015
1124
  const result = await callTool(projectRoot, 'cloud', 'create_task', {
1016
1125
  title: 'Recovered per-call token write',
@@ -1035,6 +1144,130 @@ describe('Taskforce MCP tool descriptions', () => {
1035
1144
  fs.rmSync(projectRoot, { recursive: true, force: true });
1036
1145
  }
1037
1146
  });
1147
+ it('keeps local MCP profile resolution unmetered even when cloud seats are full', async () => {
1148
+ const projectRoot = createProjectRoot();
1149
+ try {
1150
+ const core = new TaskforceCore({
1151
+ projectRoot,
1152
+ storagePath: path.join(projectRoot, '.taskforce')
1153
+ });
1154
+ core.upsertPlanCatalog({ planId: 'free', displayName: 'Free', status: 'active' });
1155
+ core.ensureBootstrapUserAccess({
1156
+ userId: 'owner-u1',
1157
+ workspaceId: 'workspace-1',
1158
+ role: 'owner',
1159
+ email: 'owner@example.com'
1160
+ });
1161
+ core.updatePlanVersionFeatures({
1162
+ planVersionId: 'free-v1',
1163
+ features: [
1164
+ { featureKey: 'collaboration.ai_profiles', access: 'limited', config: { maxAiProfiles: 1 } }
1165
+ ]
1166
+ });
1167
+ core.updateAccountEntitlement({
1168
+ accountId: 'owner-u1',
1169
+ planVersionId: 'free-v1',
1170
+ entitlementState: 'active',
1171
+ actorUserId: 'system-admin',
1172
+ actorRole: 'system_admin'
1173
+ });
1174
+ core.resolveAiProfile({
1175
+ workspaceId: 'workspace-1',
1176
+ name: 'Existing Automation Bot',
1177
+ }, { trustedSeatScope: 'cloud_metered' });
1178
+ core.close();
1179
+ const payload = parseToolJson(await callTool(projectRoot, 'local', 'resolve_profile', {
1180
+ name: 'Local Codex'
1181
+ }, {
1182
+ workspaceId: 'workspace-1',
1183
+ resolveProfile: false
1184
+ }));
1185
+ expect(payload.created).toBe(true);
1186
+ expect(payload.profile.name).toBe('Local Codex');
1187
+ expect(payload.profile.seatScope).toBe('local_unmetered');
1188
+ }
1189
+ finally {
1190
+ fs.rmSync(projectRoot, { recursive: true, force: true });
1191
+ }
1192
+ });
1193
+ it('derives profile seat scope from the MCP runtime instead of auth metadata', async () => {
1194
+ const projectRoot = createProjectRoot();
1195
+ try {
1196
+ const localRuntime = createTaskforceMcpServer({
1197
+ projectRoot,
1198
+ runtimeMode: 'local',
1199
+ workspaceId: 'workspace-1',
1200
+ logStartup: false,
1201
+ auth: {
1202
+ aiProfileSeatScope: 'cloud_metered',
1203
+ aiProfileName: 'Codex',
1204
+ aiProfileRole: 'Implementation',
1205
+ aiProfileProvider: 'OpenAI',
1206
+ aiProfileModel: 'gpt-5',
1207
+ aiProfileSurfaceType: 'coding_tool',
1208
+ }
1209
+ });
1210
+ const localPayload = parseToolJson(await callToolWithRuntime(localRuntime, 'resolve_profile', {
1211
+ name: 'Codex',
1212
+ surfaceType: 'coding_tool',
1213
+ }, {
1214
+ resolveProfile: false
1215
+ }));
1216
+ expect(localPayload.profile.seatScope).toBe('local_unmetered');
1217
+ const cloudRuntime = createTaskforceMcpServer({
1218
+ projectRoot,
1219
+ runtimeMode: 'cloud',
1220
+ workspaceId: 'workspace-1',
1221
+ logStartup: false,
1222
+ auth: {
1223
+ scopes: ['tasks:read', 'tasks:write', 'workspace:read'],
1224
+ userId: 'owner-1',
1225
+ actorType: 'oauth',
1226
+ aiProfileSeatScope: 'local_unmetered',
1227
+ aiProfileName: 'Cloud Codex',
1228
+ aiProfileSurfaceType: 'coding_tool',
1229
+ }
1230
+ });
1231
+ const cloudPayload = parseToolJson(await callToolWithRuntime(cloudRuntime, 'resolve_profile', {
1232
+ name: 'Cloud Codex',
1233
+ surfaceType: 'coding_tool',
1234
+ }, {
1235
+ resolveProfile: false
1236
+ }));
1237
+ expect(cloudPayload.profile.seatScope).toBe('cloud_metered');
1238
+ }
1239
+ finally {
1240
+ fs.rmSync(projectRoot, { recursive: true, force: true });
1241
+ }
1242
+ });
1243
+ it('creates a separate local MCP profile when a cloud profile with the same name already exists', async () => {
1244
+ const projectRoot = createProjectRoot();
1245
+ try {
1246
+ const core = new TaskforceCore({
1247
+ projectRoot,
1248
+ storagePath: path.join(projectRoot, '.taskforce')
1249
+ });
1250
+ const cloud = core.resolveAiProfile({
1251
+ workspaceId: 'workspace-1',
1252
+ name: 'Codex',
1253
+ surfaceType: 'coding_tool'
1254
+ }, { trustedSeatScope: 'cloud_metered' });
1255
+ core.close();
1256
+ const payload = parseToolJson(await callTool(projectRoot, 'local', 'resolve_profile', {
1257
+ name: 'Codex',
1258
+ surfaceType: 'coding_tool'
1259
+ }, {
1260
+ workspaceId: 'workspace-1',
1261
+ resolveProfile: false
1262
+ }));
1263
+ expect(payload.created).toBe(true);
1264
+ expect(payload.profile.id).not.toBe(cloud.profile.id);
1265
+ expect(payload.profile.seatScope).toBe('local_unmetered');
1266
+ }
1267
+ finally {
1268
+ fs.rmSync(projectRoot, { recursive: true, force: true });
1269
+ }
1270
+ });
1038
1271
  it('claims unassigned tasks and marks them in progress through start_task', async () => {
1039
1272
  const projectRoot = createProjectRoot();
1040
1273
  try {
@@ -2645,6 +2878,52 @@ describe('Taskforce MCP tool descriptions', () => {
2645
2878
  fs.rmSync(projectRoot, { recursive: true, force: true });
2646
2879
  }
2647
2880
  });
2881
+ it('accepts documented schedule helper arguments', async () => {
2882
+ const projectRoot = createProjectRoot();
2883
+ try {
2884
+ const core = new TaskforceCore({
2885
+ projectRoot,
2886
+ storagePath: path.join(projectRoot, '.taskforce')
2887
+ });
2888
+ const first = core.createTask({ title: 'First documented schedule helper test' }, { workspaceId: 'workspace-1' });
2889
+ const second = core.createTask({ title: 'Second documented schedule helper test' }, { workspaceId: 'workspace-1' });
2890
+ core.close();
2891
+ const board = parseToolJson(await callTool(projectRoot, 'local', 'get_schedule_board', {}));
2892
+ expect(board.week).toMatch(/^\d{4}-W\d{2}$/);
2893
+ const scheduled = parseToolJson(await callTool(projectRoot, 'local', 'schedule_task', {
2894
+ taskId: first.referenceLabel,
2895
+ date: '2099-01-05',
2896
+ order: 3
2897
+ }));
2898
+ expect(scheduled.scheduling.persistedDate).toBe('2099-01-05');
2899
+ expect(scheduled.scheduling.persistedOrderInDay).toBe(3);
2900
+ await callTool(projectRoot, 'local', 'reorder_scheduled_tasks', {
2901
+ date: '2099-01-05',
2902
+ taskIds: [second.referenceLabel, first.referenceLabel]
2903
+ });
2904
+ await callTool(projectRoot, 'local', 'unschedule_task', {
2905
+ taskId: first.referenceLabel
2906
+ });
2907
+ const after = new TaskforceCore({
2908
+ projectRoot,
2909
+ storagePath: path.join(projectRoot, '.taskforce')
2910
+ });
2911
+ try {
2912
+ const firstTask = after.getTask(first.id, 'workspace-1');
2913
+ const secondTask = after.getTask(second.id, 'workspace-1');
2914
+ expect(firstTask?.scheduledDate).toBeNull();
2915
+ expect(firstTask?.orderInDay).toBeNull();
2916
+ expect(secondTask?.scheduledDate).toBe('2099-01-05');
2917
+ expect(secondTask?.orderInDay).toBe(0);
2918
+ }
2919
+ finally {
2920
+ after.close();
2921
+ }
2922
+ }
2923
+ finally {
2924
+ fs.rmSync(projectRoot, { recursive: true, force: true });
2925
+ }
2926
+ });
2648
2927
  it('maps legacy agent assignee writes to unassigned even when a profile is resolved', async () => {
2649
2928
  const projectRoot = createProjectRoot();
2650
2929
  try {
@@ -1,6 +1,5 @@
1
1
  import type { DatabaseAdapter } from '../storage/databaseAdapter.js';
2
2
  export declare function ensureTenantSchema(db: DatabaseAdapter): void;
3
- export declare function ensureParentTaskSchema(db: DatabaseAdapter): void;
4
3
  export declare function ensureScheduleTaskSchema(db: DatabaseAdapter): void;
5
4
  export declare function ensureAssigneeTaskSchema(db: DatabaseAdapter): void;
6
5
  export declare function ensureTaskReferenceSchema(db: DatabaseAdapter): void;
@@ -14,3 +13,4 @@ export declare function ensureSyncEventsSchema(db: DatabaseAdapter): void;
14
13
  export declare function ensureWorkspaceDocumentsSchema(db: DatabaseAdapter): void;
15
14
  export declare function ensureAnnotatedAttachmentSessionsSchema(db: DatabaseAdapter): void;
16
15
  export declare function ensureDocumentReviewSessionsSchema(db: DatabaseAdapter): void;
16
+ export declare function ensureAuthIdentitySchema(db: DatabaseAdapter): void;