@taskforcehq/taskforce 0.3.169 → 0.3.300

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (696) hide show
  1. package/README.md +52 -21
  2. package/dist/Taskforce.module.css +3394 -5981
  3. package/dist/TaskforceCore.CategoryFallback.test.js +5 -2
  4. package/dist/TaskforceCore.filter-persistence.test.js +402 -0
  5. package/dist/TaskforceCore.js +388 -71
  6. package/dist/TaskforceCore.routing.test.js +311 -0
  7. package/dist/TaskforceCore.test.js +3344 -615
  8. package/dist/TaskforceWidget.js +3 -2
  9. package/dist/__tests__/localizationCatalogs.test.js +48 -31
  10. package/dist/__tests__/workflowSimulation.test.js +2 -2
  11. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +60 -0
  12. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +324 -0
  13. package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.js +278 -0
  14. package/dist/annotatedAttachments/payload.d.ts +2 -0
  15. package/dist/annotatedAttachments/payload.js +54 -0
  16. package/dist/annotatedAttachments/payload.test.js +67 -0
  17. package/dist/annotatedAttachments/service.d.ts +49 -0
  18. package/dist/annotatedAttachments/service.js +121 -0
  19. package/dist/annotatedAttachments/types.d.ts +86 -0
  20. package/dist/cli.js +74 -25
  21. package/dist/compat/deploymentCompat.d.ts +12 -0
  22. package/dist/compat/deploymentCompat.js +43 -0
  23. package/dist/compat/workspaceSyncCompat.d.ts +6 -0
  24. package/dist/compat/workspaceSyncCompat.js +79 -0
  25. package/dist/compat/workspaceSyncCompat.test.js +87 -0
  26. package/dist/components/features/AgentsModule.d.ts +5 -0
  27. package/dist/components/features/AgentsModule.js +131 -0
  28. package/dist/components/features/AgentsModule.test.js +102 -0
  29. package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +24 -0
  30. package/dist/components/features/AnnotatedAttachmentWorkspace.js +1942 -0
  31. package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +2831 -0
  32. package/dist/components/features/DocumentGenerateModal.js +8 -16
  33. package/dist/components/features/DocumentIndex.d.ts +3 -4
  34. package/dist/components/features/DocumentIndex.js +22 -10
  35. package/dist/components/features/DocumentViewer.d.ts +6 -2
  36. package/dist/components/features/DocumentViewer.js +1000 -18
  37. package/dist/components/features/DocumentWorkspace.d.ts +40 -2
  38. package/dist/components/features/DocumentWorkspace.js +96 -16
  39. package/dist/components/features/DocumentWorkspace.test.js +1202 -0
  40. package/dist/components/features/InitiativesModule.d.ts +22 -0
  41. package/dist/components/features/InitiativesModule.js +33 -0
  42. package/dist/components/features/TaskSettings.d.ts +41 -32
  43. package/dist/components/features/TaskSettings.js +798 -313
  44. package/dist/components/features/TaskSettings.test.js +1221 -47
  45. package/dist/components/features/WorkflowsModule.d.ts +27 -0
  46. package/dist/components/features/WorkflowsModule.js +21 -0
  47. package/dist/components/features/documentWorkspaceFilters.d.ts +10 -0
  48. package/dist/components/features/documentWorkspaceFilters.js +11 -0
  49. package/dist/components/features/settings/CategoryManager.d.ts +2 -0
  50. package/dist/components/features/settings/CategoryManager.js +15 -8
  51. package/dist/components/features/settings/PriorityManager.d.ts +18 -0
  52. package/dist/components/features/settings/PriorityManager.js +51 -0
  53. package/dist/components/features/settings/TaxonomyEditor.d.ts +2 -1
  54. package/dist/components/features/settings/TaxonomyEditor.js +41 -18
  55. package/dist/components/features/settings/TaxonomyLibraryManager.d.ts +26 -0
  56. package/dist/components/features/settings/TaxonomyLibraryManager.js +301 -0
  57. package/dist/components/features/settings/TaxonomyLibraryManager.test.js +141 -0
  58. package/dist/components/features/settings/TaxonomyManager.d.ts +35 -12
  59. package/dist/components/features/settings/TaxonomyManager.js +59 -27
  60. package/dist/components/features/settings/TypeManager.d.ts +11 -0
  61. package/dist/components/features/settings/TypeManager.js +48 -11
  62. package/dist/components/features/settings/{WorkflowEditorPrototype.d.ts → WorkflowEditor.d.ts} +2 -2
  63. package/dist/components/features/settings/{WorkflowEditorPrototype.js → WorkflowEditor.js} +3 -3
  64. package/dist/components/task/TaskActionHeader.d.ts +12 -2
  65. package/dist/components/task/TaskActionHeader.js +64 -8
  66. package/dist/components/task/TaskActionHeader.test.js +73 -0
  67. package/dist/components/task/TaskCard.d.ts +14 -16
  68. package/dist/components/task/TaskCard.js +144 -174
  69. package/dist/components/task/TaskCard.test.js +416 -64
  70. package/dist/components/task/TaskContextUpload.d.ts +6 -5
  71. package/dist/components/task/TaskContextUpload.js +199 -64
  72. package/dist/components/task/TaskContextUpload.test.js +331 -14
  73. package/dist/components/task/TaskForm.d.ts +23 -29
  74. package/dist/components/task/TaskForm.js +348 -169
  75. package/dist/components/task/TaskForm.test.js +419 -23
  76. package/dist/components/task/TaskKanban.d.ts +20 -21
  77. package/dist/components/task/TaskKanban.js +176 -316
  78. package/dist/components/task/TaskKanban.planning-drop.test.js +93 -0
  79. package/dist/components/task/TaskList.d.ts +22 -11
  80. package/dist/components/task/TaskList.js +98 -12
  81. package/dist/components/task/TaskList.test.js +206 -7
  82. package/dist/components/task/TaskReferenceBadge.d.ts +12 -0
  83. package/dist/components/task/TaskReferenceBadge.js +5 -0
  84. package/dist/components/task/TaskStatusActions.d.ts +12 -0
  85. package/dist/components/task/TaskStatusActions.js +18 -0
  86. package/dist/components/task/TaskStatusActions.test.js +45 -0
  87. package/dist/components/ui/ImageReferenceBadge.d.ts +12 -0
  88. package/dist/components/ui/ImageReferenceBadge.js +5 -0
  89. package/dist/components/ui/LevelSelector.d.ts +2 -1
  90. package/dist/components/ui/LevelSelector.js +2 -2
  91. package/dist/components/ui/Markdown.d.ts +1 -2
  92. package/dist/components/ui/Markdown.js +2 -13
  93. package/dist/components/ui/Modal.d.ts +3 -2
  94. package/dist/components/ui/Modal.js +4 -3
  95. package/dist/components/ui/MultiSelectFilter.d.ts +3 -1
  96. package/dist/components/ui/MultiSelectFilter.js +2 -2
  97. package/dist/components/ui/ReferenceBadgeButton.d.ts +13 -0
  98. package/dist/components/ui/ReferenceBadgeButton.js +6 -0
  99. package/dist/components/ui/TaxonomyDropdown.d.ts +7 -1
  100. package/dist/components/ui/TaxonomyDropdown.js +58 -23
  101. package/dist/components/ui/TopNoticeLayer.d.ts +7 -0
  102. package/dist/components/ui/TopNoticeLayer.js +14 -0
  103. package/dist/components/ui/TopNoticeLayer.test.js +25 -0
  104. package/dist/components/views/AppShellHeader.d.ts +13 -0
  105. package/dist/components/views/AppShellHeader.js +19 -0
  106. package/dist/components/views/AppShellHeader.test.js +21 -0
  107. package/dist/components/views/PlanComparisonPage.d.ts +73 -0
  108. package/dist/components/views/PlanComparisonPage.js +196 -0
  109. package/dist/components/views/PlanComparisonPage.test.js +251 -0
  110. package/dist/components/views/PlansPage.d.ts +14 -0
  111. package/dist/components/views/PlansPage.js +355 -0
  112. package/dist/components/views/StandaloneLayout.d.ts +2 -2
  113. package/dist/components/views/StandaloneLayout.js +2212 -1194
  114. package/dist/components/views/WidgetView.d.ts +2 -2
  115. package/dist/components/views/WidgetView.js +149 -43
  116. package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +57 -0
  117. package/dist/components/views/chrome/WorkspaceChromeSections.js +38 -0
  118. package/dist/components/views/chrome/WorkspaceChromeSections.test.js +54 -0
  119. package/dist/components/views/chrome/workspaceChrome.d.ts +31 -0
  120. package/dist/components/views/chrome/workspaceChrome.js +108 -0
  121. package/dist/components/views/chrome/workspaceChrome.test.js +52 -0
  122. package/dist/components/views/panels/DocumentFilterToolbar.d.ts +10 -0
  123. package/dist/components/views/panels/DocumentFilterToolbar.js +7 -0
  124. package/dist/components/views/panels/DocumentFilterToolbar.test.js +19 -0
  125. package/dist/components/views/panels/FilterToolbar.d.ts +66 -0
  126. package/dist/components/views/panels/FilterToolbar.js +21 -0
  127. package/dist/components/views/panels/FilterToolbar.test.d.ts +1 -0
  128. package/dist/components/views/panels/FilterToolbar.test.js +45 -0
  129. package/dist/components/views/panels/FilterToolbarControls.d.ts +46 -0
  130. package/dist/components/views/panels/FilterToolbarControls.js +61 -0
  131. package/dist/components/views/panels/PlanningDrawer.d.ts +115 -0
  132. package/dist/components/views/panels/PlanningDrawer.js +220 -0
  133. package/dist/components/views/panels/ScheduleSidebar.d.ts +52 -0
  134. package/dist/components/views/panels/ScheduleSidebar.js +127 -0
  135. package/dist/components/views/panels/scheduleUtils.d.ts +14 -0
  136. package/dist/components/views/panels/scheduleUtils.js +79 -0
  137. package/dist/components/views/teamManagementAccess.d.ts +6 -0
  138. package/dist/components/views/teamManagementAccess.js +18 -0
  139. package/dist/components/views/teamManagementAccess.test.d.ts +1 -0
  140. package/dist/components/views/teamManagementAccess.test.js +44 -0
  141. package/dist/config/clientDeployment.d.ts +2 -0
  142. package/dist/config/clientDeployment.js +13 -0
  143. package/dist/config/cloudEnvironment.d.ts +15 -0
  144. package/dist/config/cloudEnvironment.js +60 -0
  145. package/dist/config/deployment.d.ts +20 -0
  146. package/dist/config/deployment.js +67 -0
  147. package/dist/config/deployment.test.d.ts +1 -0
  148. package/dist/config/deployment.test.js +88 -0
  149. package/dist/config/envSchema.js +36 -8
  150. package/dist/config/envSchema.test.js +28 -0
  151. package/dist/core/AiProfileService.d.ts +66 -0
  152. package/dist/core/AiProfileService.js +320 -0
  153. package/dist/core/AiProfileService.test.d.ts +1 -0
  154. package/dist/core/AiProfileService.test.js +164 -0
  155. package/dist/core/AiProfiles.test.d.ts +1 -0
  156. package/dist/core/AiProfiles.test.js +449 -0
  157. package/dist/core/AttachmentLinkService.d.ts +15 -0
  158. package/dist/core/AttachmentLinkService.js +157 -0
  159. package/dist/core/AuthTokenService.d.ts +44 -0
  160. package/dist/core/AuthTokenService.js +207 -0
  161. package/dist/core/CreatedBy.test.js +134 -6
  162. package/dist/core/DeletedTaskLifecycleService.d.ts +33 -0
  163. package/dist/core/DeletedTaskLifecycleService.js +158 -0
  164. package/dist/core/DeletedTaskTrash.test.d.ts +1 -0
  165. package/dist/core/DeletedTaskTrash.test.js +104 -0
  166. package/dist/core/EntitlementsPolicy.test.js +78 -5
  167. package/dist/core/GlobalSettingsService.d.ts +16 -0
  168. package/dist/core/GlobalSettingsService.js +370 -0
  169. package/dist/core/JsonBackupRuntime.test.d.ts +1 -0
  170. package/dist/core/JsonBackupRuntime.test.js +155 -0
  171. package/dist/core/McpTokenService.d.ts +118 -0
  172. package/dist/core/McpTokenService.js +921 -0
  173. package/dist/core/PlanEntitlementService.d.ts +201 -0
  174. package/dist/core/PlanEntitlementService.js +1442 -0
  175. package/dist/core/PlanVersionPolicy.test.d.ts +1 -0
  176. package/dist/core/PlanVersionPolicy.test.js +178 -0
  177. package/dist/core/PlanningEntities.test.d.ts +1 -0
  178. package/dist/core/PlanningEntities.test.js +95 -0
  179. package/dist/core/ScheduleFields.test.js +15 -19
  180. package/dist/core/SignupMonetizationSettings.test.d.ts +1 -0
  181. package/dist/core/SignupMonetizationSettings.test.js +159 -0
  182. package/dist/core/Stats.test.d.ts +1 -0
  183. package/dist/core/Stats.test.js +36 -0
  184. package/dist/core/SyncReconciliationService.d.ts +93 -0
  185. package/dist/core/SyncReconciliationService.js +406 -0
  186. package/dist/core/SystemAdmin.test.js +578 -13
  187. package/dist/core/TaskActivityService.d.ts +21 -0
  188. package/dist/core/TaskActivityService.js +130 -0
  189. package/dist/core/TaskAttachmentsCanonical.test.d.ts +1 -0
  190. package/dist/core/TaskAttachmentsCanonical.test.js +306 -0
  191. package/dist/core/TaskAuditTimeline.test.d.ts +1 -0
  192. package/dist/core/TaskAuditTimeline.test.js +132 -0
  193. package/dist/core/TaskTaxonomyValidation.test.js +338 -15
  194. package/dist/core/Taskforce.d.ts +930 -183
  195. package/dist/core/Taskforce.ids.test.js +252 -0
  196. package/dist/core/Taskforce.js +3848 -2532
  197. package/dist/core/Taskforce.mcpAuth.test.d.ts +1 -0
  198. package/dist/core/Taskforce.mcpAuth.test.js +343 -0
  199. package/dist/core/Taskforce.realtimeMutation.test.js +57 -2
  200. package/dist/core/TaxonomySettingsService.d.ts +18 -0
  201. package/dist/core/TaxonomySettingsService.js +162 -0
  202. package/dist/core/WorkspaceDelete.test.js +32 -13
  203. package/dist/core/WorkspaceLifecycleService.d.ts +11 -0
  204. package/dist/core/WorkspaceLifecycleService.js +88 -0
  205. package/dist/core/WorkspacePermissions.test.js +95 -0
  206. package/dist/core/WorkspacePlanMode.test.js +114 -1
  207. package/dist/core/WorkspacePreferenceService.d.ts +41 -0
  208. package/dist/core/WorkspacePreferenceService.js +246 -0
  209. package/dist/core/WorkspaceSyncSettings.test.d.ts +1 -0
  210. package/dist/core/WorkspaceSyncSettings.test.js +65 -0
  211. package/dist/core/__tests__/TaskAttachmentsCanonical.test.d.ts +1 -0
  212. package/dist/core/__tests__/TaskAttachmentsCanonical.test.js +212 -0
  213. package/dist/core/shared.d.ts +36 -0
  214. package/dist/core/shared.js +128 -0
  215. package/dist/core/types.d.ts +614 -0
  216. package/dist/core/types.js +27 -0
  217. package/dist/documentReviews/DocumentReviewCommentStore.d.ts +56 -0
  218. package/dist/documentReviews/DocumentReviewCommentStore.js +230 -0
  219. package/dist/documentReviews/DocumentReviewSessionStore.d.ts +52 -0
  220. package/dist/documentReviews/DocumentReviewSessionStore.js +193 -0
  221. package/dist/documentReviews/DocumentReviewSessionStore.test.d.ts +1 -0
  222. package/dist/documentReviews/DocumentReviewSessionStore.test.js +127 -0
  223. package/dist/documentReviews/service.d.ts +68 -0
  224. package/dist/documentReviews/service.js +210 -0
  225. package/dist/documentReviews/types.d.ts +58 -0
  226. package/dist/documentReviews/types.js +1 -0
  227. package/dist/hooks/auth/useAuthGuardPolicy.d.ts +2 -0
  228. package/dist/hooks/auth/useAuthGuardPolicy.js +1 -0
  229. package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +15 -0
  230. package/dist/hooks/tasks/useCurrentTaskRelations.js +37 -0
  231. package/dist/hooks/tasks/useTaskActions.d.ts +3 -0
  232. package/dist/hooks/tasks/useTaskActions.js +2 -0
  233. package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +65 -0
  234. package/dist/hooks/tasks/useTaskEditorNavigation.js +235 -0
  235. package/dist/hooks/tasks/useTaskFilters.d.ts +2 -0
  236. package/dist/hooks/tasks/useTaskFilters.js +2 -0
  237. package/dist/hooks/tasks/useTaskFormActions.d.ts +58 -0
  238. package/dist/hooks/tasks/useTaskFormActions.js +365 -0
  239. package/dist/hooks/tasks/useTaskRelationships.d.ts +16 -0
  240. package/dist/hooks/tasks/useTaskRelationships.js +64 -0
  241. package/dist/hooks/ui/useResourceExport.d.ts +19 -0
  242. package/dist/hooks/ui/useResourceExport.js +84 -0
  243. package/dist/hooks/ui/useSettingsModel.d.ts +203 -0
  244. package/dist/hooks/ui/useSettingsModel.js +125 -0
  245. package/dist/hooks/ui/useSettingsPersistence.d.ts +36 -0
  246. package/dist/hooks/ui/useSettingsPersistence.js +254 -0
  247. package/dist/hooks/ui/useSettingsTaxonomyManagement.d.ts +119 -0
  248. package/dist/hooks/ui/useSettingsTaxonomyManagement.js +536 -0
  249. package/dist/hooks/ui/useUiNotice.d.ts +1 -0
  250. package/dist/hooks/ui/useUiNotice.js +1 -0
  251. package/dist/hooks/ui/useWorkflowTemplates.d.ts +37 -0
  252. package/dist/hooks/ui/useWorkflowTemplates.js +111 -0
  253. package/dist/hooks/ui/useZenMode.d.ts +5 -0
  254. package/dist/hooks/ui/useZenMode.js +32 -0
  255. package/dist/hooks/useFilterSort.d.ts +60 -0
  256. package/dist/hooks/useFilterSort.js +362 -0
  257. package/dist/hooks/useFilterSort.test.d.ts +1 -0
  258. package/dist/hooks/useFilterSort.test.js +333 -0
  259. package/dist/hooks/useRealtimeSync.d.ts +1 -0
  260. package/dist/hooks/useRealtimeSync.js +24 -9
  261. package/dist/hooks/useRealtimeSync.test.js +28 -1
  262. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.d.ts +1 -0
  263. package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +34 -0
  264. package/dist/hooks/useSyncOrchestrator.d.ts +65 -103
  265. package/dist/hooks/useSyncOrchestrator.js +1538 -670
  266. package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +700 -174
  267. package/dist/hooks/useTaskData.d.ts +35 -0
  268. package/dist/hooks/useTaskData.js +239 -0
  269. package/dist/hooks/useTaskData.test.d.ts +1 -0
  270. package/dist/hooks/useTaskData.test.js +119 -0
  271. package/dist/hooks/useTaskMutations.d.ts +46 -0
  272. package/dist/hooks/useTaskMutations.js +472 -0
  273. package/dist/hooks/useTaskMutations.test.d.ts +1 -0
  274. package/dist/hooks/useTaskMutations.test.js +80 -0
  275. package/dist/hooks/useTaskforce.contract.test.d.ts +1 -0
  276. package/dist/hooks/useTaskforce.contract.test.js +7 -0
  277. package/dist/hooks/useTaskforce.d.ts +260 -295
  278. package/dist/hooks/useTaskforce.js +1954 -2623
  279. package/dist/hooks/useTaskforce.priority-filters.test.js +6 -11
  280. package/dist/hooks/useTaskforce.sync-behavior.test.d.ts +1 -0
  281. package/dist/hooks/useTaskforce.sync-behavior.test.js +1120 -0
  282. package/dist/hooks/useUiNotice.d.ts +16 -0
  283. package/dist/hooks/useUiNotice.js +49 -0
  284. package/dist/hooks/useWorkspaceSyncController.d.ts +23 -46
  285. package/dist/hooks/useWorkspaceSyncController.js +280 -461
  286. package/dist/hooks/useWorkspaceSyncController.test.js +106 -199
  287. package/dist/hooks/workspace/useTaskforceApiRouting.d.ts +8 -0
  288. package/dist/hooks/workspace/useTaskforceApiRouting.js +91 -0
  289. package/dist/hooks/workspace/useTaskforceApiRouting.test.d.ts +1 -0
  290. package/dist/hooks/workspace/useTaskforceApiRouting.test.js +60 -0
  291. package/dist/hooks/workspace/useWorkspaceSyncController.d.ts +1 -0
  292. package/dist/hooks/workspace/useWorkspaceSyncController.js +1 -0
  293. package/dist/hooks/workspace/workspaceLocalState.d.ts +30 -0
  294. package/dist/hooks/workspace/workspaceLocalState.js +101 -0
  295. package/dist/localization/locales/en-US.d.ts +1 -8
  296. package/dist/localization/locales/en-US.js +4 -11
  297. package/dist/localization/locales/es-419.js +2 -9
  298. package/dist/localization/locales/pt-BR.js +2 -9
  299. package/dist/localization/localizationCatalogs.test.d.ts +1 -0
  300. package/dist/localization/localizationCatalogs.test.js +37 -0
  301. package/dist/main.d.ts +1 -0
  302. package/dist/main.js +9 -15
  303. package/dist/mcp/clientIntegrations.d.ts +33 -0
  304. package/dist/mcp/clientIntegrations.js +199 -0
  305. package/dist/mcp/clientIntegrations.test.d.ts +1 -0
  306. package/dist/mcp/clientIntegrations.test.js +110 -0
  307. package/dist/mcp/index.d.ts +2 -0
  308. package/dist/mcp/index.js +2 -0
  309. package/dist/mcp/optionResolution.test.js +6 -2
  310. package/dist/mcp/runtime.d.ts +120 -0
  311. package/dist/mcp/runtime.js +5668 -0
  312. package/dist/mcp/runtime.test.d.ts +1 -0
  313. package/dist/mcp/runtime.test.js +3293 -0
  314. package/dist/mcp/server.js +2 -1793
  315. package/dist/mcp/structuredCommentValidation.test.d.ts +1 -0
  316. package/dist/{__tests__ → mcp}/structuredCommentValidation.test.js +1 -1
  317. package/dist/mcp/structuredDocValidation.js +1 -2
  318. package/dist/mcp/structuredDocValidation.test.d.ts +1 -0
  319. package/dist/{__tests__ → mcp}/structuredDocValidation.test.js +9 -4
  320. package/dist/mcp/toolRegistry.d.ts +570 -0
  321. package/dist/mcp/toolRegistry.js +90 -0
  322. package/dist/mcp/toolRegistry.test.d.ts +1 -0
  323. package/dist/mcp/toolRegistry.test.js +30 -0
  324. package/dist/migrations/billingSchemaParity.test.js +111 -0
  325. package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
  326. package/dist/migrations/taskSchemaMigrations.js +681 -39
  327. package/dist/migrations/taskSchemaMigrations.test.d.ts +1 -0
  328. package/dist/migrations/taskSchemaMigrations.test.js +210 -0
  329. package/dist/plugins/vite.js +13 -7
  330. package/dist/public/apple-touch-icon.png +0 -0
  331. package/dist/public/archive/phoenix/apple-touch-icon.png +0 -0
  332. package/dist/public/archive/phoenix/favicon.ico +0 -0
  333. package/dist/public/archive/phoenix/site.webmanifest +1 -0
  334. package/dist/public/favicon-96x96.png +0 -0
  335. package/dist/public/favicon.ico +0 -0
  336. package/dist/public/favicon.svg +17 -0
  337. package/dist/public/site.webmanifest +21 -1
  338. package/dist/public/web-app-manifest-192x192.png +0 -0
  339. package/dist/public/web-app-manifest-512x512.png +0 -0
  340. package/dist/releaseVersion.test.d.ts +1 -0
  341. package/dist/{__tests__/releaseVersion.test.js → releaseVersion.test.js} +1 -1
  342. package/dist/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
  343. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
  344. package/dist/resources/templates/workflows/collaborate.yaml +11 -5
  345. package/dist/resources/templates/workflows/do.yaml +8 -2
  346. package/dist/resources/templates/workflows/evaluate.yaml +13 -7
  347. package/dist/resources/templates/workflows/execute.yaml +40 -23
  348. package/dist/resources/templates/workflows/plan.yaml +15 -8
  349. package/dist/resources/templates/workflows/review.yaml +14 -8
  350. package/dist/runtime/appGateDefinitions.d.ts +32 -0
  351. package/dist/runtime/appGateDefinitions.js +32 -0
  352. package/dist/runtime/appGates.d.ts +29 -0
  353. package/dist/runtime/appGates.js +53 -0
  354. package/dist/runtime/appGates.test.d.ts +1 -0
  355. package/dist/runtime/appGates.test.js +42 -0
  356. package/dist/runtime/migrationFlags.d.ts +1 -0
  357. package/dist/runtime/migrationFlags.js +1 -0
  358. package/dist/server/annotatedAttachmentsRoutes.test.d.ts +1 -0
  359. package/dist/server/annotatedAttachmentsRoutes.test.js +473 -0
  360. package/dist/server/auth.js +14 -2
  361. package/dist/server/auth.test.js +21 -1
  362. package/dist/server/cors.js +11 -5
  363. package/dist/server/cors.test.js +6 -0
  364. package/dist/server/documentReviewRoutes.test.d.ts +1 -0
  365. package/dist/server/documentReviewRoutes.test.js +157 -0
  366. package/dist/server/index.cookieProxy.test.js +46 -1
  367. package/dist/server/index.d.ts +20 -0
  368. package/dist/server/index.js +168 -41
  369. package/dist/server/index.rateLimit.test.js +6 -0
  370. package/dist/server/index.test.js +133 -2
  371. package/dist/server/mockStripe.d.ts +72 -0
  372. package/dist/server/mockStripe.js +357 -0
  373. package/dist/server/realtimeSyncWs.js +4 -0
  374. package/dist/server/routes/admin.d.ts +114 -0
  375. package/dist/server/routes/admin.js +2226 -0
  376. package/dist/server/routes/annotatedAttachments.d.ts +24 -0
  377. package/dist/server/routes/annotatedAttachments.js +235 -0
  378. package/dist/server/routes/auth.d.ts +61 -0
  379. package/dist/server/routes/auth.js +1296 -0
  380. package/dist/server/{routes.billing.d.ts → routes/billing.d.ts} +3 -2
  381. package/dist/server/routes/billing.js +2001 -0
  382. package/dist/server/routes/billing.test.d.ts +1 -0
  383. package/dist/server/routes/billing.test.js +1631 -0
  384. package/dist/server/routes/documentReviews.d.ts +11 -0
  385. package/dist/server/routes/documentReviews.js +191 -0
  386. package/dist/server/routes/documents.d.ts +118 -0
  387. package/dist/server/routes/documents.js +1113 -0
  388. package/dist/server/routes/resources.d.ts +25 -0
  389. package/dist/server/routes/resources.js +225 -0
  390. package/dist/server/routes/shared.d.ts +35 -0
  391. package/dist/server/routes/shared.js +305 -0
  392. package/dist/server/routes/shared.test.d.ts +1 -0
  393. package/dist/server/routes/shared.test.js +32 -0
  394. package/dist/server/{routes.sync.d.ts → routes/sync.d.ts} +5 -5
  395. package/dist/server/routes/sync.integration.test.d.ts +1 -0
  396. package/dist/server/routes/sync.integration.test.js +2003 -0
  397. package/dist/server/routes/sync.js +3143 -0
  398. package/dist/server/routes/tasks.d.ts +72 -0
  399. package/dist/server/routes/tasks.js +1252 -0
  400. package/dist/server/routes/workspaces.d.ts +32 -0
  401. package/dist/server/routes/workspaces.js +307 -0
  402. package/dist/server/routes.d.ts +8 -9
  403. package/dist/server/routes.js +968 -4092
  404. package/dist/server/routes.test.js +9043 -2415
  405. package/dist/server/runtimeMode.d.ts +1 -1
  406. package/dist/server/runtimeMode.js +3 -18
  407. package/dist/server/runtimeMode.test.js +3 -3
  408. package/dist/server/securityHeaders.d.ts +1 -1
  409. package/dist/server/securityHeaders.js +65 -6
  410. package/dist/server/securityHeaders.test.js +40 -2
  411. package/dist/services/templateEngine.test.d.ts +1 -0
  412. package/dist/{__tests__ → services}/templateEngine.test.js +1 -1
  413. package/dist/services/templates.test.d.ts +1 -0
  414. package/dist/{__tests__ → services}/templates.test.js +1 -1
  415. package/dist/services/workflowDocumentFixtures.test.d.ts +1 -0
  416. package/dist/{__tests__ → services}/workflowDocumentFixtures.test.js +4 -4
  417. package/dist/services/workflowExportMatrix.test.d.ts +1 -0
  418. package/dist/{__tests__ → services}/workflowExportMatrix.test.js +1 -1
  419. package/dist/services/workflowExportSnapshots.test.d.ts +1 -0
  420. package/dist/services/workflowGeneration.test.d.ts +1 -0
  421. package/dist/services/workflowSimulation.test.d.ts +1 -0
  422. package/dist/services/workflowSimulation.test.js +113 -0
  423. package/dist/services/workflowV2Policy.test.d.ts +1 -0
  424. package/dist/{__tests__ → services}/workflowV2Policy.test.js +2 -2
  425. package/dist/shared/aiProfileSurfaceType.d.ts +9 -0
  426. package/dist/shared/aiProfileSurfaceType.js +49 -0
  427. package/dist/shared/customTaxonomyLibrary.d.ts +11 -0
  428. package/dist/shared/customTaxonomyLibrary.js +276 -0
  429. package/dist/shared/customTaxonomyLibrary.test.d.ts +1 -0
  430. package/dist/shared/customTaxonomyLibrary.test.js +20 -0
  431. package/dist/shared/taxonomyCatalog.d.ts +19 -0
  432. package/dist/shared/taxonomyCatalog.js +36 -0
  433. package/dist/shared/taxonomyDefaults.d.ts +29 -0
  434. package/dist/shared/taxonomyDefaults.js +26 -0
  435. package/dist/shared/taxonomyLibrary.d.ts +15 -0
  436. package/dist/shared/taxonomyLibrary.js +98 -0
  437. package/dist/shared/taxonomyLibrary.test.d.ts +1 -0
  438. package/dist/shared/taxonomyLibrary.test.js +26 -0
  439. package/dist/shared/taxonomyState.d.ts +36 -0
  440. package/dist/shared/taxonomyState.js +73 -0
  441. package/dist/shared/taxonomyState.test.d.ts +1 -0
  442. package/dist/shared/taxonomyState.test.js +71 -0
  443. package/dist/shared/workflowDefaults.d.ts +9 -0
  444. package/dist/shared/workflowDefaults.js +11 -0
  445. package/dist/storage/documentIntegrity.d.ts +2 -0
  446. package/dist/storage/documentIntegrity.js +34 -17
  447. package/dist/storage/documentPurge.d.ts +2 -1
  448. package/dist/storage/documentPurge.js +35 -8
  449. package/dist/storage/index.d.ts +4 -0
  450. package/dist/storage/index.js +2 -0
  451. package/dist/storage/objectStorage.d.ts +1 -1
  452. package/dist/storage/objectStorageClient.d.ts +6 -4
  453. package/dist/storage/objectStorageClient.js +77 -29
  454. package/dist/storage/objectStorageClient.test.d.ts +1 -0
  455. package/dist/storage/objectStorageClient.test.js +57 -0
  456. package/dist/storage/objectStorageConfig.js +3 -1
  457. package/dist/storage/objectStorageConfig.test.d.ts +1 -0
  458. package/dist/storage/objectStorageConfig.test.js +38 -0
  459. package/dist/storage/postgresAdapter.d.ts +5 -0
  460. package/dist/storage/postgresAdapter.js +2 -2
  461. package/dist/storage/postgresAdapter.test.d.ts +1 -0
  462. package/dist/storage/postgresAdapter.test.js +29 -0
  463. package/dist/storage/taskAssetStore.d.ts +7 -4
  464. package/dist/storage/taskAssetStore.js +65 -60
  465. package/dist/storage/workspaceAssetStore.d.ts +122 -0
  466. package/dist/storage/workspaceAssetStore.js +496 -0
  467. package/dist/storage/workspaceAssetStore.test.d.ts +1 -0
  468. package/dist/storage/workspaceAssetStore.test.js +501 -0
  469. package/dist/sync/cloudSyncApi.d.ts +33 -2
  470. package/dist/sync/cloudSyncApi.js +37 -15
  471. package/dist/sync/cloudSyncApi.test.js +60 -3
  472. package/dist/sync/index.d.ts +2 -0
  473. package/dist/sync/index.js +3 -0
  474. package/dist/sync/syncService.d.ts +25 -0
  475. package/dist/sync/syncService.js +184 -16
  476. package/dist/sync/syncService.test.js +289 -25
  477. package/dist/sync/workspaceRepair.d.ts +114 -0
  478. package/dist/sync/workspaceRepair.js +566 -0
  479. package/dist/sync/workspaceSyncModel.d.ts +230 -2
  480. package/dist/sync/workspaceSyncModel.js +456 -17
  481. package/dist/sync/workspaceSyncModel.test.js +642 -0
  482. package/dist/sync/workspaceSyncState.d.ts +12 -0
  483. package/dist/sync/workspaceSyncState.js +12 -0
  484. package/dist/sync/workspaceSyncSurface.d.ts +33 -0
  485. package/dist/sync/workspaceSyncSurface.js +74 -0
  486. package/dist/types.d.ts +143 -18
  487. package/dist/types.js +9 -24
  488. package/dist/ui/assets/AgentsModule-TVmCgizS.js +1 -0
  489. package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +1 -0
  490. package/dist/ui/assets/AnnotatedAttachmentWorkspace-CAyhnPeR.js +3 -0
  491. package/dist/ui/assets/DocumentWorkspace-BOCw5e4D.js +250 -0
  492. package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +1 -0
  493. package/dist/ui/assets/InitiativesModule-CN0r02Oi.js +1 -0
  494. package/dist/ui/assets/PlansPage-BlVC_lRq.css +1 -0
  495. package/dist/ui/assets/PlansPage-FcQSNLZd.js +1 -0
  496. package/dist/ui/assets/TaskSettings-BwB9NtmJ.css +1 -0
  497. package/dist/ui/assets/TaskSettings-Cw5zYD1L.js +8 -0
  498. package/dist/ui/assets/WorkflowsModule-CY9R2zPB.js +5 -0
  499. package/dist/ui/assets/index-Bzqy5QGm.js +6 -0
  500. package/dist/ui/assets/index-DxRiI3tY.css +1 -0
  501. package/dist/ui/assets/vendor-dnd-DRzYolkg.js +5 -0
  502. package/dist/ui/assets/{vendor-icons-ZFG3SGwo.js → vendor-icons-QZyhEwgT.js} +1 -1
  503. package/dist/ui/assets/{vendor-markdown-CKYkQHfj.js → vendor-markdown-BUxTU7dS.js} +1 -1
  504. package/dist/ui/assets/vendor-react-CKJs5o3c.js +61 -0
  505. package/dist/ui/assets/vendor-router-BbWMxlnO.js +3 -0
  506. package/dist/ui/branding/logos/logo.png +0 -0
  507. package/dist/ui/branding/logos/logo_dark.svg +27 -0
  508. package/dist/ui/branding/logos/logo_favicon.svg +35 -0
  509. package/dist/ui/branding/logos/logo_light.svg +27 -0
  510. package/dist/ui/favicon/apple-touch-icon.png +0 -0
  511. package/dist/ui/favicon/archive/phoenix/apple-touch-icon.png +0 -0
  512. package/dist/ui/favicon/archive/phoenix/favicon.ico +0 -0
  513. package/dist/ui/favicon/archive/phoenix/site.webmanifest +1 -0
  514. package/dist/ui/favicon/favicon-96x96.png +0 -0
  515. package/dist/ui/favicon/favicon.ico +0 -0
  516. package/dist/ui/favicon/favicon.svg +17 -0
  517. package/dist/ui/favicon/site.webmanifest +21 -1
  518. package/dist/ui/favicon/web-app-manifest-192x192.png +0 -0
  519. package/dist/ui/favicon/web-app-manifest-512x512.png +0 -0
  520. package/dist/ui/index.html +10 -7
  521. package/dist/ui/product/screen_01.png +0 -0
  522. package/dist/ui/product/screen_02.png +0 -0
  523. package/dist/ui/product/screen_03.png +0 -0
  524. package/dist/utils/annotatedAttachments.d.ts +20 -0
  525. package/dist/utils/annotatedAttachments.js +74 -0
  526. package/dist/utils/annotatedAttachments.test.d.ts +1 -0
  527. package/dist/utils/annotatedAttachments.test.js +108 -0
  528. package/dist/utils/assignees.d.ts +26 -0
  529. package/dist/utils/assignees.js +132 -0
  530. package/dist/utils/canonicalAssetKind.d.ts +16 -0
  531. package/dist/utils/canonicalAssetKind.js +39 -0
  532. package/dist/utils/canonicalAssetKind.test.d.ts +1 -0
  533. package/dist/utils/canonicalAssetKind.test.js +24 -0
  534. package/dist/utils/coalescedRefresh.d.ts +5 -0
  535. package/dist/utils/coalescedRefresh.js +16 -0
  536. package/dist/utils/coalescedRefresh.test.d.ts +1 -0
  537. package/dist/utils/coalescedRefresh.test.js +30 -0
  538. package/dist/utils/constants.d.ts +16 -3
  539. package/dist/utils/constants.icons.test.js +2 -1
  540. package/dist/utils/constants.js +70 -13
  541. package/dist/utils/contextAssetEvents.d.ts +7 -0
  542. package/dist/utils/contextAssetEvents.js +6 -0
  543. package/dist/utils/contextFiles.d.ts +14 -3
  544. package/dist/utils/contextFiles.js +40 -8
  545. package/dist/utils/documentManagerApi.d.ts +6 -0
  546. package/dist/utils/documentManagerApi.js +19 -0
  547. package/dist/utils/documentNames.d.ts +24 -0
  548. package/dist/utils/documentNames.js +91 -0
  549. package/dist/utils/documentReferences.d.ts +9 -0
  550. package/dist/utils/documentReferences.js +11 -0
  551. package/dist/utils/entityReferences.d.ts +9 -0
  552. package/dist/utils/entityReferences.js +32 -0
  553. package/dist/utils/imageReferences.d.ts +9 -0
  554. package/dist/utils/imageReferences.js +11 -0
  555. package/dist/utils/planParser.d.ts +2 -2
  556. package/dist/utils/planParser.js +11 -11
  557. package/dist/utils/planParser.test.d.ts +1 -0
  558. package/dist/{__tests__ → utils}/planParser.test.js +22 -22
  559. package/dist/utils/planningReferences.d.ts +17 -0
  560. package/dist/utils/planningReferences.js +30 -0
  561. package/dist/utils/planningReferences.test.d.ts +1 -0
  562. package/dist/utils/planningReferences.test.js +17 -0
  563. package/dist/utils/taskActivity.d.ts +9 -0
  564. package/dist/utils/taskActivity.js +147 -0
  565. package/dist/utils/taskActivity.test.d.ts +1 -0
  566. package/dist/utils/taskActivity.test.js +34 -0
  567. package/dist/utils/taskDraftDefaults.d.ts +21 -0
  568. package/dist/utils/taskDraftDefaults.js +40 -0
  569. package/dist/utils/taskDraftDefaults.test.d.ts +1 -0
  570. package/dist/utils/taskDraftDefaults.test.js +34 -0
  571. package/dist/utils/taskNormalization.d.ts +25 -0
  572. package/dist/utils/taskNormalization.js +161 -0
  573. package/dist/utils/taskNormalization.test.d.ts +1 -0
  574. package/dist/utils/taskNormalization.test.js +158 -0
  575. package/dist/utils/taskReferences.d.ts +5 -0
  576. package/dist/utils/taskReferences.js +11 -0
  577. package/dist/utils/taskforceApiClient.d.ts +2 -0
  578. package/dist/utils/taskforceApiClient.js +101 -3
  579. package/dist/utils/taskforceApiClient.test.d.ts +1 -0
  580. package/dist/utils/taskforceApiClient.test.js +44 -0
  581. package/dist/utils/taxonomyFilterOptions.d.ts +2 -0
  582. package/dist/utils/taxonomyFilterOptions.js +17 -0
  583. package/dist/utils/taxonomyFormDefaults.d.ts +3 -0
  584. package/dist/utils/taxonomyFormDefaults.js +28 -0
  585. package/dist/utils/taxonomyFormDefaults.test.d.ts +1 -0
  586. package/dist/utils/taxonomyFormDefaults.test.js +63 -0
  587. package/dist/utils/taxonomyLifecycle.d.ts +3 -0
  588. package/dist/utils/taxonomyLifecycle.js +17 -0
  589. package/dist/utils/taxonomySorting.d.ts +7 -0
  590. package/dist/utils/taxonomySorting.js +74 -0
  591. package/dist/utils/theme.d.ts +15 -0
  592. package/dist/utils/theme.js +23 -0
  593. package/dist/utils/uiNotice.d.ts +7 -0
  594. package/dist/utils/uiNotice.js +6 -0
  595. package/dist/utils/uiNotice.test.d.ts +1 -0
  596. package/dist/utils/uiNotice.test.js +18 -0
  597. package/dist/utils/workspaceIdentity.d.ts +14 -0
  598. package/dist/utils/workspaceIdentity.js +21 -0
  599. package/dist/utils/workspaceIdentity.test.js +30 -1
  600. package/dist/utils/workspaceSyncPresentation.d.ts +20 -0
  601. package/dist/utils/workspaceSyncPresentation.js +21 -0
  602. package/dist/utils/workspaceSyncPresentation.test.d.ts +1 -0
  603. package/dist/utils/workspaceSyncPresentation.test.js +36 -0
  604. package/package.json +28 -23
  605. package/scripts/bootstrap-playwright-auth.mjs +155 -0
  606. package/scripts/check-compat-boundaries.mjs +41 -0
  607. package/scripts/check-env.ts +9 -2
  608. package/scripts/debug-login.mjs +32 -0
  609. package/scripts/migrate-planning-model.ts +233 -0
  610. package/scripts/migrate-task-data-assets.mjs +408 -0
  611. package/scripts/playwright-auth.sh +11 -0
  612. package/scripts/run-dev-proxy.sh +2 -0
  613. package/scripts/update-homebrew-formula.sh +20 -3
  614. package/scripts/with-esbuild.sh +11 -0
  615. package/src/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
  616. package/src/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
  617. package/src/resources/templates/workflows/collaborate.yaml +11 -5
  618. package/src/resources/templates/workflows/do.yaml +8 -2
  619. package/src/resources/templates/workflows/evaluate.yaml +13 -7
  620. package/src/resources/templates/workflows/execute.yaml +40 -23
  621. package/src/resources/templates/workflows/plan.yaml +15 -8
  622. package/src/resources/templates/workflows/review.yaml +14 -8
  623. package/dist/TaskforceScreenshot.d.ts +0 -11
  624. package/dist/TaskforceScreenshot.js +0 -113
  625. package/dist/compat/priorityCompat.d.ts +0 -2
  626. package/dist/compat/priorityCompat.js +0 -24
  627. package/dist/components/features/settings/TaxonomyManager 2.d.ts +0 -52
  628. package/dist/components/features/settings/TaxonomyManager 2.js +0 -75
  629. package/dist/components/task/TaskKanban 2.d.ts +0 -76
  630. package/dist/components/task/TaskKanban 2.js +0 -1004
  631. package/dist/components/task/TaskScreenshotSection.d.ts +0 -15
  632. package/dist/components/task/TaskScreenshotSection.js +0 -22
  633. package/dist/components/views/StandaloneLayout 2.d.ts +0 -8
  634. package/dist/components/views/StandaloneLayout 2.js +0 -1660
  635. package/dist/core/InitiativeTemplates.test.js +0 -50
  636. package/dist/core/ParentLifecycle.test.js +0 -98
  637. package/dist/migrations/clientMigrations.d.ts +0 -9
  638. package/dist/migrations/clientMigrations.js +0 -74
  639. package/dist/migrations/flags.d.ts +0 -6
  640. package/dist/migrations/flags.js +0 -8
  641. package/dist/migrations/taskMigrations.d.ts +0 -71
  642. package/dist/migrations/taskMigrations.js +0 -236
  643. package/dist/migrations/taskMigrations.test.js +0 -34
  644. package/dist/server/routes.billing.js +0 -991
  645. package/dist/server/routes.billing.test.js +0 -387
  646. package/dist/server/routes.sync.integration.test.js +0 -470
  647. package/dist/server/routes.sync.js +0 -1141
  648. package/dist/soak/syncSoakHarness.d.ts +0 -6
  649. package/dist/soak/syncSoakHarness.js +0 -10
  650. package/dist/ui/assets/index-0W5vyCpn.css +0 -1
  651. package/dist/ui/assets/index-MCZuNNfn.js +0 -23
  652. package/dist/ui/assets/logo_white_01-0Vx-iIIv.png +0 -0
  653. package/dist/ui/assets/vendor-dnd-BI1K77C1.js +0 -5
  654. package/dist/ui/assets/vendor-react-DdIDsh7f.js +0 -9
  655. package/dist/ui/assets/vendor-router-BtiNU7Dl.js +0 -3
  656. package/dist/utils/taskHierarchy.d.ts +0 -4
  657. package/dist/utils/taskHierarchy.js +0 -69
  658. package/dist/utils/taskHierarchy.test.js +0 -38
  659. package/dist/utils/taskParenting.d.ts +0 -3
  660. package/dist/utils/taskParenting.js +0 -24
  661. package/dist/utils/taskParenting.test.js +0 -21
  662. package/dist/utils/taskRelations.d.ts +0 -6
  663. package/dist/utils/taskRelations.js +0 -24
  664. package/dist/utils/taskRelations.test.js +0 -34
  665. package/scripts/check-compat-boundaries.js +0 -48
  666. /package/dist/{__tests__/planParser.test.d.ts → TaskforceCore.filter-persistence.test.d.ts} +0 -0
  667. /package/dist/{__tests__/releaseVersion.test.d.ts → TaskforceCore.routing.test.d.ts} +0 -0
  668. /package/dist/{__tests__/structuredCommentValidation.test.d.ts → annotatedAttachments/AnnotatedAttachmentSessionStore.test.d.ts} +0 -0
  669. /package/dist/{__tests__/structuredDocValidation.test.d.ts → annotatedAttachments/payload.test.d.ts} +0 -0
  670. /package/dist/{__tests__/templateEngine.test.d.ts → annotatedAttachments/types.js} +0 -0
  671. /package/dist/{__tests__/templates.test.d.ts → compat/workspaceSyncCompat.test.d.ts} +0 -0
  672. /package/dist/{__tests__/workflowDocumentFixtures.test.d.ts → components/features/AgentsModule.test.d.ts} +0 -0
  673. /package/dist/{__tests__/workflowExportMatrix.test.d.ts → components/features/AnnotatedAttachmentWorkspace.test.d.ts} +0 -0
  674. /package/dist/{__tests__/workflowExportSnapshots.test.d.ts → components/features/DocumentWorkspace.test.d.ts} +0 -0
  675. /package/dist/{__tests__/workflowGeneration.test.d.ts → components/features/settings/TaxonomyLibraryManager.test.d.ts} +0 -0
  676. /package/dist/{__tests__/workflowV2Policy.test.d.ts → components/task/TaskActionHeader.test.d.ts} +0 -0
  677. /package/dist/{core/InitiativeTemplates.test.d.ts → components/task/TaskKanban.planning-drop.test.d.ts} +0 -0
  678. /package/dist/{core/ParentLifecycle.test.d.ts → components/task/TaskStatusActions.test.d.ts} +0 -0
  679. /package/dist/{migrations/taskMigrations.test.d.ts → components/ui/TopNoticeLayer.test.d.ts} +0 -0
  680. /package/dist/{server/routes.billing.test.d.ts → components/views/AppShellHeader.test.d.ts} +0 -0
  681. /package/dist/{server/routes.sync.integration.test.d.ts → components/views/PlanComparisonPage.test.d.ts} +0 -0
  682. /package/dist/{utils/taskHierarchy.test.d.ts → components/views/chrome/WorkspaceChromeSections.test.d.ts} +0 -0
  683. /package/dist/{utils/taskParenting.test.d.ts → components/views/chrome/workspaceChrome.test.d.ts} +0 -0
  684. /package/dist/{utils/taskRelations.test.d.ts → components/views/panels/DocumentFilterToolbar.test.d.ts} +0 -0
  685. /package/dist/public/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
  686. /package/dist/public/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
  687. /package/dist/public/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
  688. /package/dist/public/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
  689. /package/dist/public/{favicon.png → archive/phoenix/favicon.png} +0 -0
  690. /package/dist/{__tests__ → services}/workflowExportSnapshots.test.js +0 -0
  691. /package/dist/{__tests__ → services}/workflowGeneration.test.js +0 -0
  692. /package/dist/ui/favicon/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
  693. /package/dist/ui/favicon/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
  694. /package/dist/ui/favicon/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
  695. /package/dist/ui/favicon/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
  696. /package/dist/ui/favicon/{favicon.png → archive/phoenix/favicon.png} +0 -0
@@ -1,1793 +1,2 @@
1
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { CallToolRequestSchema, ListResourceTemplatesRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
- import * as fs from 'fs';
5
- import * as path from 'path';
6
- import { TaskforceCore } from '../core/Taskforce.js'; // Note .js extension for ESM
7
- import { COMPLEXITY_OPTIONS, resolveNumberOption, resolveStringOption, STATUS_OPTIONS } from './optionResolution.js';
8
- import { validateStructuredDocForAttach } from './structuredDocValidation.js';
9
- import { validateStructuredCommentForAdd } from './structuredCommentValidation.js';
10
- import { resolveDatabaseConfigFromEnv } from '../storage/providerConfig.js';
11
- // Initialize Core
12
- // We need to find project root.
13
- // In dev (tsx), we are in src/mcp/server.ts.
14
- // In prod (dist), we are in dist/mcp/server.js.
15
- // Project root is likely 2 levels up.
16
- const PROJECT_ROOT = process.argv[2]
17
- ? path.resolve(process.argv[2])
18
- : path.resolve(process.cwd());
19
- const PROJECT_NAME = path.basename(PROJECT_ROOT);
20
- console.error(`[Taskforce MCP] Starting for project: ${PROJECT_NAME} at ${PROJECT_ROOT}`);
21
- const db = resolveDatabaseConfigFromEnv();
22
- const tenantId = String(process.env.TASKFORCE_TENANT_ID || 'default').trim() || 'default';
23
- const MCP_SERVER_VERSION = (() => {
24
- try {
25
- const packagePath = path.resolve(PROJECT_ROOT, 'package.json');
26
- const raw = fs.readFileSync(packagePath, 'utf-8');
27
- const parsed = JSON.parse(raw);
28
- const version = String(parsed?.version || '').trim();
29
- return version || '0.0.0-dev';
30
- }
31
- catch {
32
- return '0.0.0-dev';
33
- }
34
- })();
35
- const core = new TaskforceCore({
36
- projectRoot: PROJECT_ROOT,
37
- tenantId,
38
- database: {
39
- provider: db.provider,
40
- connectionString: db.connectionString
41
- }
42
- });
43
- const workspaceFromEnv = String(process.env.TASKFORCE_WORKSPACE_ID || '').trim();
44
- let ACTIVE_WORKSPACE_ID = '';
45
- const workspaceFromEnvValid = workspaceFromEnv && workspaceFromEnv.toLowerCase() !== 'default'
46
- ? workspaceFromEnv
47
- : '';
48
- if (workspaceFromEnv && !workspaceFromEnvValid) {
49
- console.warn('[Taskforce MCP] Ignoring TASKFORCE_WORKSPACE_ID=default. Resolving non-default workspace automatically.');
50
- }
51
- if (workspaceFromEnvValid) {
52
- if (!core.workspaceExists(workspaceFromEnv)) {
53
- throw new Error(`[Taskforce MCP] Configured workspace not found for tenant ${tenantId}: ${workspaceFromEnv}`);
54
- }
55
- ACTIVE_WORKSPACE_ID = workspaceFromEnvValid;
56
- }
57
- else {
58
- const inferredWorkspaceId = core.resolvePreferredWorkspaceId({ allowDefault: false });
59
- if (!inferredWorkspaceId) {
60
- throw new Error('[Taskforce MCP] Unable to resolve workspace scope. Set TASKFORCE_WORKSPACE_ID explicitly.');
61
- }
62
- ACTIVE_WORKSPACE_ID = inferredWorkspaceId;
63
- }
64
- console.error(`[Taskforce MCP] Scope resolved: tenant=${tenantId} workspace=${ACTIVE_WORKSPACE_ID}`);
65
- const server = new Server({
66
- name: `taskforce-${PROJECT_NAME}`,
67
- version: MCP_SERVER_VERSION,
68
- }, {
69
- capabilities: {
70
- resources: {
71
- subscribe: true,
72
- listChanged: true,
73
- },
74
- tools: {},
75
- },
76
- });
77
- /**
78
- * Helpers
79
- */
80
- function renderTaskTable(tasks) {
81
- if (tasks.length === 0)
82
- return "No tasks found.";
83
- let table = "| ID | Title | Status | Assignee | Category | Priority |\n";
84
- table += "|---|---|---|---|---|---|\n";
85
- for (const task of tasks) {
86
- table += `| \`${task.id}\` | ${task.title} | \`${task.status}\` | \`${task.assignee || 'unassigned'}\` | ${task.category} | ${task.priority} |\n`;
87
- }
88
- return table;
89
- }
90
- function isHttpUrl(value) {
91
- return /^https?:\/\//i.test(value);
92
- }
93
- function isWithinRoot(filePath, root) {
94
- const relative = path.relative(root, filePath);
95
- return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
96
- }
97
- function toPosixPath(filePath) {
98
- return filePath.split(path.sep).join('/');
99
- }
100
- function sanitizeTaskIdForPath(taskIdRaw) {
101
- const value = typeof taskIdRaw === 'string' ? taskIdRaw.trim() : '';
102
- if (!value)
103
- return '_unassigned';
104
- return value.replace(/[^a-zA-Z0-9._-]/g, '-');
105
- }
106
- function sanitizeFilenameForPath(filenameRaw, fallback = 'attachment.txt') {
107
- const value = typeof filenameRaw === 'string' ? filenameRaw.trim() : '';
108
- const basename = path.basename(value || fallback);
109
- const sanitized = basename
110
- .replace(/[^a-zA-Z0-9._-]/g, '-')
111
- .replace(/^\.+/, '');
112
- return sanitized || fallback;
113
- }
114
- function nextAvailablePath(targetPath) {
115
- if (!fs.existsSync(targetPath))
116
- return targetPath;
117
- const parsed = path.parse(targetPath);
118
- let counter = 2;
119
- while (true) {
120
- const nextPath = path.join(parsed.dir, `${parsed.name}-${counter}${parsed.ext}`);
121
- if (!fs.existsSync(nextPath))
122
- return nextPath;
123
- counter += 1;
124
- }
125
- }
126
- function buildRelationshipAuditComment(taskId, previousParentId, nextParentId) {
127
- if (previousParentId === nextParentId)
128
- return null;
129
- if (!previousParentId && !nextParentId)
130
- return null;
131
- const timestamp = new Date().toISOString();
132
- if (!previousParentId && nextParentId) {
133
- return [
134
- '## AI Relationship Audit',
135
- '### Action',
136
- 'link-child',
137
- '### Task',
138
- taskId,
139
- '### From Parent',
140
- 'none',
141
- '### To Parent',
142
- nextParentId,
143
- '### Timestamp',
144
- timestamp
145
- ].join('\n');
146
- }
147
- if (previousParentId && !nextParentId) {
148
- return [
149
- '## AI Relationship Audit',
150
- '### Action',
151
- 'unlink-child',
152
- '### Task',
153
- taskId,
154
- '### From Parent',
155
- previousParentId,
156
- '### To Parent',
157
- 'none',
158
- '### Timestamp',
159
- timestamp
160
- ].join('\n');
161
- }
162
- return [
163
- '## AI Relationship Audit',
164
- '### Action',
165
- 're-parent-child',
166
- '### Task',
167
- taskId,
168
- '### From Parent',
169
- previousParentId,
170
- '### To Parent',
171
- nextParentId,
172
- '### Timestamp',
173
- timestamp
174
- ].join('\n');
175
- }
176
- function buildBatchSummary(params) {
177
- const failed = Math.max(0, params.total - params.succeeded);
178
- return {
179
- operation: params.operation,
180
- total: params.total,
181
- succeeded: params.succeeded,
182
- failed,
183
- partial: params.succeeded > 0 && failed > 0
184
- };
185
- }
186
- function parseDateOnlyLocal(dateOnly) {
187
- const match = String(dateOnly || '').trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);
188
- if (!match)
189
- return null;
190
- const date = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
191
- if (Number.isNaN(date.getTime()))
192
- return null;
193
- return date;
194
- }
195
- function formatDateOnlyLocal(date) {
196
- const y = date.getFullYear();
197
- const m = String(date.getMonth() + 1).padStart(2, '0');
198
- const d = String(date.getDate()).padStart(2, '0');
199
- return `${y}-${m}-${d}`;
200
- }
201
- function addDaysDateOnly(dateOnly, days) {
202
- const parsed = parseDateOnlyLocal(dateOnly);
203
- if (!parsed)
204
- return null;
205
- const next = new Date(parsed);
206
- next.setDate(parsed.getDate() + days);
207
- return formatDateOnlyLocal(next);
208
- }
209
- function normalizeScheduleFieldAliases(input) {
210
- const next = { ...input };
211
- if (next.scheduledDate === undefined && next.scheduleDate !== undefined) {
212
- next.scheduledDate = next.scheduleDate;
213
- }
214
- if (next.scheduledWeekKey === undefined && next.scheduleWeekKey !== undefined) {
215
- next.scheduledWeekKey = next.scheduleWeekKey;
216
- }
217
- delete next.scheduleDate;
218
- delete next.scheduleWeekKey;
219
- return next;
220
- }
221
- const RESOURCE_URI_PREFIX = `taskforce://${PROJECT_NAME}`;
222
- const RESOURCE_CONFIG_URI = `${RESOURCE_URI_PREFIX}/config`;
223
- const RESOURCE_STATS_URI = `${RESOURCE_URI_PREFIX}/stats`;
224
- const RESOURCE_TASKS_URI = `${RESOURCE_URI_PREFIX}/tasks`;
225
- const RESOURCE_TASK_TEMPLATE_URI = `${RESOURCE_URI_PREFIX}/tasks/{id}`;
226
- const resourceSubscriptions = new Set();
227
- const ASSIGNEE_OPTIONS = [
228
- { value: 'unassigned', label: 'Unassigned' },
229
- { value: 'agent', label: 'Agent' },
230
- { value: 'user', label: 'User' }
231
- ];
232
- function taskUriFor(id) {
233
- return `${RESOURCE_URI_PREFIX}/tasks/${encodeURIComponent(id)}`;
234
- }
235
- function parseTaskIdFromUri(uri) {
236
- if (!uri.startsWith(`${RESOURCE_URI_PREFIX}/tasks/`))
237
- return null;
238
- const encodedId = uri.slice(`${RESOURCE_URI_PREFIX}/tasks/`.length).trim();
239
- if (!encodedId)
240
- return null;
241
- return decodeURIComponent(encodedId);
242
- }
243
- function isSupportedResourceUri(uri) {
244
- return uri === RESOURCE_CONFIG_URI
245
- || uri === RESOURCE_STATS_URI
246
- || uri === RESOURCE_TASKS_URI
247
- || parseTaskIdFromUri(uri) !== null;
248
- }
249
- async function notifyResourceUpdatedIfSubscribed(uri) {
250
- if (!resourceSubscriptions.has(uri))
251
- return;
252
- try {
253
- await server.sendResourceUpdated({ uri });
254
- }
255
- catch (error) {
256
- console.error(`[Taskforce MCP] Failed to send resources/updated for ${uri}: ${error.message}`);
257
- }
258
- }
259
- async function notifyResourceMutation(options) {
260
- const uris = new Set();
261
- if (options.includeConfig)
262
- uris.add(RESOURCE_CONFIG_URI);
263
- if (options.includeStats)
264
- uris.add(RESOURCE_STATS_URI);
265
- if (options.includeTasks)
266
- uris.add(RESOURCE_TASKS_URI);
267
- for (const taskId of options.taskIds ?? []) {
268
- if (taskId && typeof taskId === 'string') {
269
- uris.add(taskUriFor(taskId));
270
- }
271
- }
272
- for (const uri of uris) {
273
- await notifyResourceUpdatedIfSubscribed(uri);
274
- }
275
- }
276
- function buildConfigResourcePayload() {
277
- return {
278
- project: {
279
- name: PROJECT_NAME,
280
- root: PROJECT_ROOT,
281
- },
282
- categories: core.getCategories(),
283
- types: core.getTypes(),
284
- priorities: core.getPriorities(),
285
- approaches: core.getApproaches(),
286
- };
287
- }
288
- function buildTasksResourcePayload() {
289
- const tasks = core.listTasks(ACTIVE_WORKSPACE_ID).tasks;
290
- return {
291
- total: tasks.length,
292
- tasks,
293
- };
294
- }
295
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
296
- return {
297
- resources: [
298
- {
299
- uri: RESOURCE_CONFIG_URI,
300
- name: `${PROJECT_NAME} Config`,
301
- title: `${PROJECT_NAME} Project Configuration`,
302
- description: "Resolved Taskforce categories, types, priorities, and approaches.",
303
- mimeType: "application/json",
304
- },
305
- {
306
- uri: RESOURCE_STATS_URI,
307
- name: `${PROJECT_NAME} Stats`,
308
- title: `${PROJECT_NAME} Task Statistics`,
309
- description: "Current active and archived task counts by status and priority.",
310
- mimeType: "application/json",
311
- },
312
- {
313
- uri: RESOURCE_TASKS_URI,
314
- name: `${PROJECT_NAME} Tasks`,
315
- title: `${PROJECT_NAME} Active Task List`,
316
- description: "All active tasks as JSON.",
317
- mimeType: "application/json",
318
- },
319
- ],
320
- };
321
- });
322
- server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
323
- return {
324
- resourceTemplates: [
325
- {
326
- uriTemplate: RESOURCE_TASK_TEMPLATE_URI,
327
- name: `${PROJECT_NAME} Task`,
328
- title: `${PROJECT_NAME} Task By ID`,
329
- description: "Read one task by ID. Example URI: " + taskUriFor("task-123"),
330
- mimeType: "application/json",
331
- },
332
- ],
333
- };
334
- });
335
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
336
- const uri = request.params.uri;
337
- if (uri === RESOURCE_CONFIG_URI) {
338
- return {
339
- contents: [
340
- {
341
- uri,
342
- mimeType: "application/json",
343
- text: JSON.stringify(buildConfigResourcePayload(), null, 2),
344
- },
345
- ],
346
- };
347
- }
348
- if (uri === RESOURCE_STATS_URI) {
349
- return {
350
- contents: [
351
- {
352
- uri,
353
- mimeType: "application/json",
354
- text: JSON.stringify(core.getStats(ACTIVE_WORKSPACE_ID), null, 2),
355
- },
356
- ],
357
- };
358
- }
359
- if (uri === RESOURCE_TASKS_URI) {
360
- return {
361
- contents: [
362
- {
363
- uri,
364
- mimeType: "application/json",
365
- text: JSON.stringify(buildTasksResourcePayload(), null, 2),
366
- },
367
- ],
368
- };
369
- }
370
- const taskId = parseTaskIdFromUri(uri);
371
- if (taskId) {
372
- const task = core.getTask(taskId, ACTIVE_WORKSPACE_ID);
373
- if (!task) {
374
- throw new Error(`Task not found for URI: ${uri}`);
375
- }
376
- return {
377
- contents: [
378
- {
379
- uri,
380
- mimeType: "application/json",
381
- text: JSON.stringify(task, null, 2),
382
- },
383
- ],
384
- };
385
- }
386
- throw new Error(`Unknown resource URI: ${uri}`);
387
- });
388
- server.setRequestHandler(SubscribeRequestSchema, async (request) => {
389
- const uri = request.params.uri;
390
- if (!isSupportedResourceUri(uri)) {
391
- throw new Error(`Unsupported resource URI for subscribe: ${uri}`);
392
- }
393
- resourceSubscriptions.add(uri);
394
- return {};
395
- });
396
- server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
397
- const uri = request.params.uri;
398
- if (!isSupportedResourceUri(uri)) {
399
- throw new Error(`Unsupported resource URI for unsubscribe: ${uri}`);
400
- }
401
- resourceSubscriptions.delete(uri);
402
- return {};
403
- });
404
- /**
405
- * Tool Definitions
406
- */
407
- server.setRequestHandler(ListToolsRequestSchema, async () => {
408
- const priorities = core.getPriorities();
409
- const approaches = core.getApproaches();
410
- const types = core.getTypes();
411
- const priorityDesc = "Priority level: " + priorities.map(p => `${p.value} (${p.label})`).join(', ');
412
- const approachEnum = approaches.map(a => a.value);
413
- const typeEnum = types.map(t => t.value);
414
- const complexityDesc = "Complexity level: 1 (Tiny), 2 (Low), 3 (Medium), 4 (High), 5 (Epic)";
415
- const optionPreflight = "Before setting category/type/priority/approach/status/complexity, call get_config to read current valid values. ";
416
- const prefix = `[Project: ${PROJECT_NAME}] `;
417
- const agentNote = " NOTE: Use this tool instead of editing files directly to ensure data integrity.";
418
- return {
419
- tools: [
420
- {
421
- name: "list_tasks",
422
- description: prefix + "List all active task items." + agentNote,
423
- inputSchema: {
424
- type: "object",
425
- properties: {
426
- format: { type: "string", enum: ["markdown", "json"], description: "Toggle output format (default: markdown)" },
427
- category: { type: "string", description: "Filter by category" },
428
- status: { type: "string", enum: ["task", "on-hold", "in-progress", "review", "done", "cancelled"], description: "Filter by status" },
429
- parentTaskId: { type: "string", description: "Filter by parent task ID (direct children only)." },
430
- openOnly: { type: "boolean", description: "When true, only include open tasks (task, on-hold, in-progress, review)." },
431
- assignee: { type: "string", enum: ["unassigned", "agent", "user"], description: "Filter by assignee" },
432
- priority: { type: "number", description: "Filter by priority level" },
433
- type: { type: "string", enum: typeEnum, description: "Filter by task type" },
434
- sort: { type: "string", enum: ["priority", "created", "updated"], description: "Sort field (default: created)" },
435
- order: { type: "string", enum: ["asc", "desc"], description: "Sort order (default: desc)" },
436
- limit: { type: "number", description: "Max tasks to return" }
437
- },
438
- },
439
- },
440
- {
441
- name: "search_tasks",
442
- description: prefix + "Search for tasks (active and archived) by query string." + agentNote,
443
- inputSchema: {
444
- type: "object",
445
- properties: {
446
- query: { type: "string", description: "Search term (matches title, description, or ID)" },
447
- scope: { type: "string", enum: ["all", "active", "archive"], description: "Search scope (default: all)" }
448
- },
449
- required: ["query"]
450
- }
451
- },
452
- {
453
- name: "get_task",
454
- description: prefix + "Get a specific task item by ID (checks active and archive)" + agentNote,
455
- inputSchema: {
456
- type: "object",
457
- properties: {
458
- id: { type: "string" }
459
- },
460
- required: ["id"],
461
- },
462
- },
463
- {
464
- name: "get_schedule_board",
465
- description: prefix + "Get schedule board state for a target week (backlog/expired/day columns)." + agentNote,
466
- inputSchema: {
467
- type: "object",
468
- properties: {
469
- week: { type: "string", description: "ISO week key (e.g., 2026-W08)" },
470
- showWeekends: { type: "boolean", description: "Include Saturday/Sunday columns (default: false)" }
471
- },
472
- required: ["week"],
473
- },
474
- },
475
- {
476
- name: "schedule_task",
477
- description: prefix + "Schedule a task to a date/order. Leaf-only validation and scheduling warnings are enforced." + agentNote,
478
- inputSchema: {
479
- type: "object",
480
- properties: {
481
- id: { type: "string" },
482
- scheduledDate: { type: "string", description: "Date-only value (YYYY-MM-DD)" },
483
- orderInDay: { type: "number", description: "Optional order index within the scheduled day" }
484
- },
485
- required: ["id", "scheduledDate"],
486
- },
487
- },
488
- {
489
- name: "unschedule_task",
490
- description: prefix + "Move a task back to backlog by clearing schedule fields." + agentNote,
491
- inputSchema: {
492
- type: "object",
493
- properties: {
494
- id: { type: "string" }
495
- },
496
- required: ["id"],
497
- },
498
- },
499
- {
500
- name: "reorder_scheduled_tasks",
501
- description: prefix + "Apply multiple schedule/date/order moves in one operation." + agentNote,
502
- inputSchema: {
503
- type: "object",
504
- properties: {
505
- moves: {
506
- type: "array",
507
- items: {
508
- type: "object",
509
- properties: {
510
- id: { type: "string" },
511
- scheduledDate: { type: ["string", "null"] },
512
- orderInDay: { type: "number" }
513
- },
514
- required: ["id", "scheduledDate"]
515
- }
516
- }
517
- },
518
- required: ["moves"],
519
- },
520
- },
521
- {
522
- name: "bulk_carryover",
523
- description: prefix + "Carry over unfinished scheduled tasks by day or week." + agentNote,
524
- inputSchema: {
525
- type: "object",
526
- properties: {
527
- fromWeek: { type: "string", description: "Source ISO week key (e.g., 2026-W08)" },
528
- toWeek: { type: "string", description: "Target ISO week key (currently informational; date shift is mode-based)" },
529
- mode: { type: "string", enum: ["day", "week"], description: "Shift scheduled dates by 1 day or 7 days" },
530
- includeStatuses: {
531
- type: "array",
532
- items: { type: "string", enum: ["task", "on-hold", "in-progress", "review", "done", "cancelled"] },
533
- description: "Statuses eligible for carryover (default: task,in-progress,review,on-hold)"
534
- }
535
- },
536
- required: ["fromWeek", "toWeek", "mode"],
537
- },
538
- },
539
- {
540
- name: "set_schedule_preferences",
541
- description: prefix + "Persist schedule preferences used by planning flows." + agentNote,
542
- inputSchema: {
543
- type: "object",
544
- properties: {
545
- showWeekends: { type: "boolean" },
546
- isCalendarSidebarOpen: { type: "boolean" },
547
- dailyCapacity: {
548
- type: "object",
549
- properties: {
550
- monday: { type: "number" },
551
- tuesday: { type: "number" },
552
- wednesday: { type: "number" },
553
- thursday: { type: "number" },
554
- friday: { type: "number" },
555
- saturday: { type: "number" },
556
- sunday: { type: "number" }
557
- }
558
- }
559
- },
560
- },
561
- },
562
- {
563
- name: "create_task",
564
- description: prefix + "Create a new task item. " + optionPreflight + agentNote,
565
- inputSchema: {
566
- type: "object",
567
- properties: {
568
- title: { type: "string" },
569
- description: { type: "string" },
570
- category: { type: "string" },
571
- type: { type: "string", enum: typeEnum },
572
- priority: { type: "number", description: priorityDesc },
573
- complexity: { type: "number", description: complexityDesc },
574
- status: { type: "string", enum: ["task", "on-hold", "in-progress", "review"], description: "Initial status (default: task)" },
575
- approach: { type: "string", enum: approachEnum },
576
- assignee: { type: "string", enum: ["unassigned", "agent", "user"], description: "Task owner assignment" },
577
- owner: { type: "string", enum: ["unassigned", "agent", "user"], description: "Alias for assignee (task owner assignment)" },
578
- scheduledDate: { type: "string", description: "Optional schedule date in YYYY-MM-DD format" },
579
- dueDate: { type: "string", description: "Optional due date in YYYY-MM-DD format" },
580
- orderInDay: { type: "number", description: "Optional sort order within scheduledDate" },
581
- parentTaskId: { type: "string", description: "Optional parent task ID. Empty/omitted means top-level task." },
582
- childDisplayOrder: { type: "number", description: "Optional display-only child order index (lower comes first among siblings)." },
583
- specialists: { type: "array", items: { type: "string" }, description: "List of specialist skill IDs to assign" }
584
- },
585
- required: ["title"],
586
- },
587
- },
588
- {
589
- name: "update_task",
590
- description: prefix + "Update an existing task item. " + optionPreflight + "Status reflects workflow state (task/on-hold/in-progress/review/done/cancelled). Archiving moves tasks to history - use archive_task for that." + agentNote,
591
- inputSchema: {
592
- type: "object",
593
- properties: {
594
- id: { type: "string" },
595
- title: { type: "string" },
596
- description: { type: "string" },
597
- category: { type: "string" },
598
- type: { type: "string", enum: typeEnum },
599
- priority: { type: "number", description: priorityDesc },
600
- complexity: { type: "number", description: complexityDesc },
601
- approach: { type: "string", enum: approachEnum },
602
- assignee: { type: "string", enum: ["unassigned", "agent", "user"], description: "Task owner assignment" },
603
- owner: { type: "string", enum: ["unassigned", "agent", "user"], description: "Alias for assignee (task owner assignment)" },
604
- scheduledDate: { type: "string", description: "Set schedule date (YYYY-MM-DD)" },
605
- dueDate: { type: "string", description: "Set due date (YYYY-MM-DD)" },
606
- orderInDay: { type: "number", description: "Set order index within scheduledDate" },
607
- status: { type: "string", enum: ["task", "on-hold", "in-progress", "review", "done", "cancelled"] },
608
- parentTaskId: { type: "string", description: "Set to a parent task ID, or empty string to unlink." },
609
- childDisplayOrder: { type: "number", description: "Optional display-only child order index (lower comes first among siblings)." },
610
- specialists: { type: "array", items: { type: "string" }, description: "Update list of assigned specialists" },
611
- canceledReason: { type: "string", description: "Reason for cancellation" }
612
- },
613
- required: ["id"],
614
- },
615
- },
616
- {
617
- name: "assign_task",
618
- description: prefix + "Assign a task owner explicitly (user/agent/unassigned)." + agentNote,
619
- inputSchema: {
620
- type: "object",
621
- properties: {
622
- id: { type: "string" },
623
- assignee: { type: "string", enum: ["unassigned", "agent", "user"] }
624
- },
625
- required: ["id", "assignee"],
626
- },
627
- },
628
- {
629
- name: "bulk_assign_tasks",
630
- description: prefix + "Assign many tasks to one owner explicitly (user/agent/unassigned)." + agentNote,
631
- inputSchema: {
632
- type: "object",
633
- properties: {
634
- ids: { type: "array", items: { type: "string" } },
635
- assignee: { type: "string", enum: ["unassigned", "agent", "user"] }
636
- },
637
- required: ["ids", "assignee"],
638
- },
639
- },
640
- {
641
- name: "archive_task",
642
- description: prefix + "Archive a task item (moving to history). This is the preferred way to 'remove' completed or cancelled tasks." + agentNote,
643
- inputSchema: {
644
- type: "object",
645
- properties: {
646
- id: { type: "string" },
647
- status: { type: "string", enum: ["done", "cancelled"], description: "Final status when archiving" },
648
- reason: { type: "string", description: "Reason for cancellation" }
649
- },
650
- required: ["id", "status"],
651
- },
652
- },
653
- {
654
- name: "add_comment",
655
- description: prefix + "Add a comment to a task item." + agentNote,
656
- inputSchema: {
657
- type: "object",
658
- properties: {
659
- id: { type: "string" },
660
- text: { type: "string" },
661
- author: { type: "string", description: "Comment author identity. Use 'user' for human comments, or AI identifiers such as 'ai', 'codex', 'antigravity', 'claude', etc." }
662
- },
663
- required: ["id", "text", "author"],
664
- },
665
- },
666
- {
667
- name: "attach_context_file",
668
- description: prefix + "Attach a project file or URL to a task as context. Local files must be inside the project root." + agentNote,
669
- inputSchema: {
670
- type: "object",
671
- properties: {
672
- id: { type: "string", description: "Task ID" },
673
- path: { type: "string", description: "File path (absolute or project-relative) or an http(s) URL" },
674
- caption: { type: "string", description: "Optional label shown in task context" }
675
- },
676
- required: ["id", "path"],
677
- },
678
- },
679
- {
680
- name: "save_task_attachment",
681
- description: prefix + "Save task-specific content or a copied file into .taskforce/task-data/{taskId}/attachments and attach it to the task." + agentNote,
682
- inputSchema: {
683
- type: "object",
684
- properties: {
685
- id: { type: "string", description: "Task ID" },
686
- filename: { type: "string", description: "Target filename in the task attachments folder." },
687
- content: { type: "string", description: "Text/markdown file content to save. Provide either content or sourcePath." },
688
- sourcePath: { type: "string", description: "Project-relative or absolute source file path to copy. Provide either sourcePath or content." },
689
- caption: { type: "string", description: "Optional label shown in task context" },
690
- overwrite: { type: "boolean", description: "Overwrite the destination file when it already exists (default: false)." }
691
- },
692
- required: ["id", "filename"],
693
- },
694
- },
695
- {
696
- name: "list_archive",
697
- description: prefix + "List all archived task items." + agentNote,
698
- inputSchema: {
699
- type: "object",
700
- properties: {
701
- format: { type: "string", enum: ["markdown", "json"], description: "Toggle output format (default: markdown)" }
702
- },
703
- },
704
- },
705
- {
706
- name: "unarchive_task",
707
- description: prefix + "Move a task from archive back to active." + agentNote,
708
- inputSchema: {
709
- type: "object",
710
- properties: {
711
- id: { type: "string" }
712
- },
713
- required: ["id"],
714
- },
715
- },
716
- {
717
- name: "bulk_archive",
718
- description: prefix + "Archive multiple task items at once." + agentNote,
719
- inputSchema: {
720
- type: "object",
721
- properties: {
722
- ids: { type: "array", items: { type: "string" } },
723
- status: { type: "string", enum: ["done", "cancelled"], description: "Status for all archived items (default: done)" }
724
- },
725
- required: ["ids"],
726
- },
727
- },
728
- {
729
- name: "get_config",
730
- description: prefix + "Get full Taskforce configuration (types, priorities, approaches, categories)." + agentNote,
731
- inputSchema: {
732
- type: "object",
733
- properties: {},
734
- },
735
- },
736
- {
737
- name: "update_categories",
738
- description: prefix + "Update category definitions." + agentNote,
739
- inputSchema: {
740
- type: "object",
741
- properties: {
742
- categories: {
743
- type: "array",
744
- items: {
745
- type: "object",
746
- properties: {
747
- value: { type: "string" },
748
- label: { type: "string" },
749
- icon: { type: "string" },
750
- color: { type: "string" }
751
- },
752
- required: ["value", "label"]
753
- }
754
- }
755
- },
756
- required: ["categories"],
757
- },
758
- },
759
- {
760
- name: "update_types",
761
- description: prefix + "Update task type definitions." + agentNote,
762
- inputSchema: {
763
- type: "object",
764
- properties: {
765
- types: {
766
- type: "array",
767
- items: {
768
- type: "object",
769
- properties: {
770
- value: { type: "string" },
771
- label: { type: "string" }
772
- },
773
- required: ["value", "label"]
774
- }
775
- }
776
- },
777
- required: ["types"],
778
- },
779
- },
780
- {
781
- name: "bulk_update_type",
782
- description: prefix + "Change the type of multiple tasks." + agentNote,
783
- inputSchema: {
784
- type: "object",
785
- properties: {
786
- fromType: { type: "string" },
787
- toType: { type: "string" }
788
- },
789
- required: ["fromType", "toType"],
790
- },
791
- },
792
- {
793
- name: "bulk_update_fields",
794
- description: prefix + "Update specific fields for multiple tasks at once. Efficient for batch operations like reprioritizing or recategorizing. " + optionPreflight + agentNote,
795
- inputSchema: {
796
- type: "object",
797
- properties: {
798
- updates: {
799
- type: "array",
800
- items: {
801
- type: "object",
802
- properties: {
803
- id: { type: "string" },
804
- title: { type: "string" },
805
- description: { type: "string" },
806
- category: { type: "string" },
807
- type: { type: "string", enum: typeEnum },
808
- priority: { type: "number", description: priorityDesc },
809
- complexity: { type: "number", description: complexityDesc },
810
- approach: { type: "string", enum: approachEnum },
811
- assignee: { type: "string", enum: ["unassigned", "agent", "user"] },
812
- owner: { type: "string", enum: ["unassigned", "agent", "user"], description: "Alias for assignee" },
813
- status: { type: "string", enum: ["task", "on-hold", "in-progress", "review", "done", "cancelled"] },
814
- specialists: { type: "array", items: { type: "string" } }
815
- },
816
- required: ["id"]
817
- }
818
- }
819
- },
820
- required: ["updates"],
821
- },
822
- },
823
- {
824
- name: "list_skills",
825
- description: prefix + "List available skills (also known as agents or specialists)." + agentNote,
826
- inputSchema: {
827
- type: "object",
828
- properties: {},
829
- },
830
- },
831
- {
832
- name: "export_resources",
833
- description: prefix + "Export templates (workflows/skills) to the project." + agentNote,
834
- inputSchema: {
835
- type: "object",
836
- properties: {
837
- type: { type: "string", enum: ["workflows", "skills"] },
838
- path: { type: "string" },
839
- variables: { type: "object", additionalProperties: { type: "string" } },
840
- environment: { type: "string", enum: ["aider", "antigravity", "claude", "cline", "codex", "copilot", "cursor", "gemini", "windsurf"], description: "Target environment/IDE" }
841
- },
842
- required: ["type", "path"],
843
- },
844
- },
845
- {
846
- name: "get_paths",
847
- description: prefix + "Get project and storage paths." + agentNote,
848
- inputSchema: {
849
- type: "object",
850
- properties: {},
851
- },
852
- },
853
- {
854
- name: "update_priorities",
855
- description: prefix + "Update priority level definitions." + agentNote,
856
- inputSchema: {
857
- type: "object",
858
- properties: {
859
- priorities: {
860
- type: "array",
861
- items: {
862
- type: "object",
863
- properties: {
864
- value: { type: "number" },
865
- label: { type: "string" },
866
- color: { type: "string" },
867
- icon: { type: "string" }
868
- },
869
- required: ["value", "label"]
870
- }
871
- }
872
- },
873
- required: ["priorities"],
874
- },
875
- },
876
- {
877
- name: "update_approaches",
878
- description: prefix + "Update approach definitions." + agentNote,
879
- inputSchema: {
880
- type: "object",
881
- properties: {
882
- approaches: {
883
- type: "array",
884
- items: {
885
- type: "object",
886
- properties: {
887
- value: { type: "string" },
888
- label: { type: "string" },
889
- color: { type: "string" },
890
- icon: { type: "string" }
891
- },
892
- required: ["value", "label"]
893
- }
894
- }
895
- },
896
- required: ["approaches"],
897
- },
898
- },
899
- {
900
- name: "get_stats",
901
- description: prefix + "Get task statistics for situational awareness (counts by status, priority, etc)." + agentNote,
902
- inputSchema: {
903
- type: "object",
904
- properties: {},
905
- },
906
- }
907
- ],
908
- };
909
- });
910
- /**
911
- * Tool Execution
912
- */
913
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
914
- const { name, arguments: args } = request.params;
915
- try {
916
- switch (name) {
917
- case "list_tasks": {
918
- const { format = "markdown", category, status, parentTaskId, openOnly = false, assignee, priority, type, sort = "created", order = "desc", limit } = args;
919
- let data = core.listTasks(ACTIVE_WORKSPACE_ID);
920
- let tasks = data.tasks;
921
- const openStatuses = new Set(["task", "on-hold", "in-progress", "review"]);
922
- // Filtering
923
- if (category)
924
- tasks = tasks.filter(t => t.category === category);
925
- if (status)
926
- tasks = tasks.filter(t => t.status === status);
927
- if (parentTaskId !== undefined) {
928
- const normalizedParentTaskId = String(parentTaskId || "").trim();
929
- tasks = tasks.filter(t => (t.parentTaskId || "") === normalizedParentTaskId);
930
- }
931
- if (openOnly)
932
- tasks = tasks.filter(t => openStatuses.has(t.status));
933
- if (assignee)
934
- tasks = tasks.filter(t => (t.assignee || 'unassigned') === assignee);
935
- if (priority !== undefined)
936
- tasks = tasks.filter(t => t.priority === Number(priority));
937
- if (type)
938
- tasks = tasks.filter(t => t.type === type);
939
- // Sorting
940
- tasks.sort((a, b) => {
941
- let aVal, bVal;
942
- if (sort === "priority") {
943
- aVal = a.priority;
944
- bVal = b.priority;
945
- }
946
- else if (sort === "updated") {
947
- aVal = a.updatedAt || a.createdAt;
948
- bVal = b.updatedAt || b.createdAt;
949
- }
950
- else {
951
- aVal = a.createdAt;
952
- bVal = b.createdAt;
953
- }
954
- const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
955
- return order === "asc" ? cmp : -cmp;
956
- });
957
- // Limiting
958
- if (limit && limit > 0) {
959
- tasks = tasks.slice(0, limit);
960
- }
961
- if (format === "json") {
962
- return {
963
- content: [{ type: "text", text: JSON.stringify(tasks, null, 2) }],
964
- };
965
- }
966
- return {
967
- content: [{ type: "text", text: renderTaskTable(tasks) }],
968
- };
969
- }
970
- case "search_tasks": {
971
- const { query, scope = "all" } = args;
972
- const results = core.searchTasks(query, scope, ACTIVE_WORKSPACE_ID);
973
- return {
974
- content: [{ type: "text", text: renderTaskTable(results) }],
975
- };
976
- }
977
- case "get_task": {
978
- const { id } = args;
979
- const task = core.getTask(id, ACTIVE_WORKSPACE_ID);
980
- if (!task) {
981
- throw new Error(`Task ${id} not found`);
982
- }
983
- return {
984
- content: [{ type: "text", text: JSON.stringify(task, null, 2) }],
985
- };
986
- }
987
- case "get_schedule_board": {
988
- const { week, showWeekends = false } = args;
989
- if (!week || typeof week !== 'string') {
990
- throw new Error('week is required');
991
- }
992
- const board = core.getScheduleBoard(week, Boolean(showWeekends), ACTIVE_WORKSPACE_ID);
993
- return {
994
- content: [{ type: "text", text: JSON.stringify(board, null, 2) }],
995
- };
996
- }
997
- case "schedule_task": {
998
- const { id, scheduledDate, orderInDay } = args;
999
- if (!id || typeof id !== 'string')
1000
- throw new Error('id is required');
1001
- if (!scheduledDate || typeof scheduledDate !== 'string')
1002
- throw new Error('scheduledDate is required');
1003
- const result = core.updateTaskSchedule(id, { scheduledDate, orderInDay }, ACTIVE_WORKSPACE_ID);
1004
- if (!result) {
1005
- throw new Error(`Task ${id} not found`);
1006
- }
1007
- await notifyResourceMutation({
1008
- taskIds: [id],
1009
- includeTasks: true,
1010
- includeStats: true,
1011
- });
1012
- return {
1013
- content: [{
1014
- type: "text",
1015
- text: JSON.stringify({
1016
- success: true,
1017
- scheduling: {
1018
- taskId: id,
1019
- requestedDate: scheduledDate,
1020
- persistedDate: result.task.scheduledDate,
1021
- persistedWeekKey: result.task.scheduledWeekKey,
1022
- persistedOrderInDay: result.task.orderInDay ?? null
1023
- },
1024
- warnings: result.warnings,
1025
- task: result.task
1026
- }, null, 2)
1027
- }],
1028
- };
1029
- }
1030
- case "unschedule_task": {
1031
- const { id } = args;
1032
- if (!id || typeof id !== 'string')
1033
- throw new Error('id is required');
1034
- const result = core.updateTaskSchedule(id, { scheduledDate: null, orderInDay: null }, ACTIVE_WORKSPACE_ID);
1035
- if (!result) {
1036
- throw new Error(`Task ${id} not found`);
1037
- }
1038
- await notifyResourceMutation({
1039
- taskIds: [id],
1040
- includeTasks: true,
1041
- includeStats: true,
1042
- });
1043
- return {
1044
- content: [{
1045
- type: "text",
1046
- text: JSON.stringify({
1047
- success: true,
1048
- scheduling: {
1049
- taskId: id,
1050
- requestedDate: null,
1051
- persistedDate: result.task.scheduledDate,
1052
- persistedWeekKey: result.task.scheduledWeekKey,
1053
- persistedOrderInDay: result.task.orderInDay ?? null
1054
- },
1055
- warnings: result.warnings,
1056
- task: result.task
1057
- }, null, 2)
1058
- }],
1059
- };
1060
- }
1061
- case "reorder_scheduled_tasks": {
1062
- const { moves } = args;
1063
- if (!Array.isArray(moves)) {
1064
- throw new Error('moves must be an array');
1065
- }
1066
- const result = core.reorderScheduledTasks(moves, ACTIVE_WORKSPACE_ID);
1067
- await notifyResourceMutation({
1068
- taskIds: moves.map((m) => m?.id).filter((id) => typeof id === 'string'),
1069
- includeTasks: true,
1070
- includeStats: true,
1071
- });
1072
- return {
1073
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
1074
- };
1075
- }
1076
- case "bulk_carryover": {
1077
- const { fromWeek, toWeek, mode, includeStatuses = ['task', 'in-progress', 'review', 'on-hold'] } = args;
1078
- if (!fromWeek || typeof fromWeek !== 'string')
1079
- throw new Error('fromWeek is required');
1080
- if (!toWeek || typeof toWeek !== 'string')
1081
- throw new Error('toWeek is required');
1082
- if (mode !== 'day' && mode !== 'week')
1083
- throw new Error('mode must be "day" or "week"');
1084
- const shiftDays = mode === 'day' ? 1 : 7;
1085
- const activeStatuses = Array.isArray(includeStatuses) ? includeStatuses.map((s) => String(s)) : [];
1086
- const tasks = core.listTasks(ACTIVE_WORKSPACE_ID).tasks.filter((task) => {
1087
- if (!task.scheduledDate)
1088
- return false;
1089
- if (task.scheduledWeekKey !== fromWeek)
1090
- return false;
1091
- if (task.status === 'done' || task.status === 'cancelled')
1092
- return false;
1093
- return activeStatuses.length === 0 || activeStatuses.includes(task.status);
1094
- });
1095
- const updates = [];
1096
- for (const task of tasks) {
1097
- const nextDate = addDaysDateOnly(String(task.scheduledDate), shiftDays);
1098
- if (!nextDate)
1099
- continue;
1100
- core.updateTaskSchedule(task.id, { scheduledDate: nextDate, orderInDay: task.orderInDay ?? undefined }, ACTIVE_WORKSPACE_ID);
1101
- updates.push({ id: task.id, from: String(task.scheduledDate), to: nextDate });
1102
- }
1103
- await notifyResourceMutation({
1104
- taskIds: updates.map(u => u.id),
1105
- includeTasks: true,
1106
- includeStats: true,
1107
- });
1108
- return {
1109
- content: [{
1110
- type: "text",
1111
- text: JSON.stringify({
1112
- fromWeek,
1113
- toWeek,
1114
- mode,
1115
- shiftedDays: shiftDays,
1116
- moved: updates.length,
1117
- updates
1118
- }, null, 2)
1119
- }],
1120
- };
1121
- }
1122
- case "set_schedule_preferences": {
1123
- const { showWeekends, isCalendarSidebarOpen, dailyCapacity } = args;
1124
- const schedulePreferences = {
1125
- ...(typeof showWeekends === 'boolean' ? { showWeekends } : {}),
1126
- ...(typeof isCalendarSidebarOpen === 'boolean' ? { isCalendarSidebarOpen } : {}),
1127
- ...(dailyCapacity && typeof dailyCapacity === 'object' ? { dailyCapacity } : {})
1128
- };
1129
- core.updateGlobalSettings({ schedulePreferences });
1130
- const updated = core.getGlobalSettings();
1131
- await notifyResourceMutation({
1132
- includeConfig: true,
1133
- });
1134
- return {
1135
- content: [{
1136
- type: "text",
1137
- text: JSON.stringify({
1138
- success: true,
1139
- schedulePreferences: updated.schedulePreferences || {}
1140
- }, null, 2)
1141
- }],
1142
- };
1143
- }
1144
- case "create_task": {
1145
- const createArgs = normalizeScheduleFieldAliases(args);
1146
- const createAssigneeInput = createArgs.assignee ?? createArgs.owner;
1147
- const normalized = {
1148
- category: resolveStringOption('category', createArgs.category, core.getCategories().map(c => ({ value: c.value, label: c.label }))),
1149
- type: resolveStringOption('type', createArgs.type, core.getTypes().map(t => ({ value: t.value, label: t.label }))),
1150
- priority: resolveNumberOption('priority', createArgs.priority, core.getPriorities().map(p => ({ value: p.value, label: p.label }))),
1151
- approach: resolveStringOption('approach', createArgs.approach, core.getApproaches().map(a => ({ value: a.value, label: a.label }))),
1152
- assignee: resolveStringOption('assignee', createAssigneeInput, [...ASSIGNEE_OPTIONS]),
1153
- status: resolveStringOption('status', createArgs.status, STATUS_OPTIONS),
1154
- complexity: resolveNumberOption('complexity', createArgs.complexity, COMPLEXITY_OPTIONS)
1155
- };
1156
- const task = core.createTask({
1157
- ...createArgs,
1158
- ...normalized,
1159
- createdBy: 'AI Agent'
1160
- }, { workspaceId: ACTIVE_WORKSPACE_ID });
1161
- if (task?.id) {
1162
- const nextParentId = typeof task.parentTaskId === 'string' && task.parentTaskId.trim().length > 0
1163
- ? task.parentTaskId.trim()
1164
- : null;
1165
- const auditComment = buildRelationshipAuditComment(task.id, null, nextParentId);
1166
- if (auditComment) {
1167
- core.addComment(task.id, auditComment, 'ai', ACTIVE_WORKSPACE_ID);
1168
- }
1169
- }
1170
- await notifyResourceMutation({
1171
- taskIds: task?.id ? [task.id] : [],
1172
- includeTasks: true,
1173
- includeStats: true,
1174
- });
1175
- return {
1176
- content: [{ type: "text", text: JSON.stringify(task, null, 2) }],
1177
- };
1178
- }
1179
- case "update_task": {
1180
- const normalizedArgs = normalizeScheduleFieldAliases(args);
1181
- const { id, status, category, priority, type, approach, assignee, owner, complexity, ...updates } = normalizedArgs;
1182
- const existingTask = core.getTask(id, ACTIVE_WORKSPACE_ID);
1183
- if (!existingTask) {
1184
- throw new Error(`Task ${id} not found`);
1185
- }
1186
- // Safety Guard: Remove any fields that are set to our internal placeholder "%SAME%"
1187
- Object.keys(updates).forEach(key => {
1188
- const value = updates[key];
1189
- if (typeof value === 'string' && (value === '%SAME%' || value === '%SAME% ')) {
1190
- delete updates[key];
1191
- }
1192
- });
1193
- // Explicitly protect ID from being updated via the updates object
1194
- delete updates.id;
1195
- delete updates.owner;
1196
- const updateAssigneeInput = assignee ?? owner;
1197
- const normalized = {
1198
- category: resolveStringOption('category', category, core.getCategories().map(c => ({ value: c.value, label: c.label }))),
1199
- type: resolveStringOption('type', type, core.getTypes().map(t => ({ value: t.value, label: t.label }))),
1200
- priority: resolveNumberOption('priority', priority, core.getPriorities().map(p => ({ value: p.value, label: p.label }))),
1201
- approach: resolveStringOption('approach', approach, core.getApproaches().map(a => ({ value: a.value, label: a.label }))),
1202
- assignee: resolveStringOption('assignee', updateAssigneeInput, [...ASSIGNEE_OPTIONS]),
1203
- status: resolveStringOption('status', status, STATUS_OPTIONS),
1204
- complexity: resolveNumberOption('complexity', complexity, COMPLEXITY_OPTIONS)
1205
- };
1206
- const finalUpdates = {
1207
- ...updates,
1208
- ...(normalized.category !== undefined ? { category: normalized.category } : {}),
1209
- ...(normalized.type !== undefined ? { type: normalized.type } : {}),
1210
- ...(normalized.priority !== undefined ? { priority: normalized.priority } : {}),
1211
- ...(normalized.approach !== undefined ? { approach: normalized.approach } : {}),
1212
- ...(normalized.assignee !== undefined ? { assignee: normalized.assignee } : {}),
1213
- ...(normalized.complexity !== undefined ? { complexity: normalized.complexity } : {})
1214
- };
1215
- // If status is provided, update it. This NO LONGER auto-archives.
1216
- if (normalized.status) {
1217
- finalUpdates.status = normalized.status;
1218
- }
1219
- const updated = core.updateTask(id, finalUpdates, ACTIVE_WORKSPACE_ID);
1220
- if (!updated) {
1221
- throw new Error(`Task ${id} not found`);
1222
- }
1223
- const previousParentId = typeof existingTask.parentTaskId === 'string' && existingTask.parentTaskId.trim().length > 0
1224
- ? existingTask.parentTaskId.trim()
1225
- : null;
1226
- const nextParentId = typeof updated.parentTaskId === 'string' && updated.parentTaskId.trim().length > 0
1227
- ? updated.parentTaskId.trim()
1228
- : null;
1229
- const auditComment = buildRelationshipAuditComment(id, previousParentId, nextParentId);
1230
- if (auditComment) {
1231
- core.addComment(id, auditComment, 'ai', ACTIVE_WORKSPACE_ID);
1232
- }
1233
- await notifyResourceMutation({
1234
- taskIds: [id],
1235
- includeTasks: true,
1236
- includeStats: true,
1237
- });
1238
- return {
1239
- content: [{ type: "text", text: JSON.stringify(updated, null, 2) }],
1240
- };
1241
- }
1242
- case "assign_task": {
1243
- const { id, assignee } = args;
1244
- if (!id || typeof id !== 'string')
1245
- throw new Error('id is required');
1246
- const resolvedAssignee = resolveStringOption('assignee', assignee, [...ASSIGNEE_OPTIONS]);
1247
- if (!resolvedAssignee)
1248
- throw new Error('assignee is required');
1249
- const updated = core.updateTask(id, { assignee: resolvedAssignee }, ACTIVE_WORKSPACE_ID);
1250
- if (!updated)
1251
- throw new Error(`Task ${id} not found`);
1252
- await notifyResourceMutation({
1253
- taskIds: [id],
1254
- includeTasks: true,
1255
- includeStats: true,
1256
- });
1257
- return {
1258
- content: [{ type: "text", text: JSON.stringify(updated, null, 2) }],
1259
- };
1260
- }
1261
- case "bulk_assign_tasks": {
1262
- const { ids, assignee } = args;
1263
- const list = Array.isArray(ids) ? ids : [];
1264
- if (list.length === 0)
1265
- throw new Error('ids array is required');
1266
- const resolvedAssignee = resolveStringOption('assignee', assignee, [...ASSIGNEE_OPTIONS]);
1267
- if (!resolvedAssignee)
1268
- throw new Error('assignee is required');
1269
- const updates = list.map((id) => ({ id, assignee: resolvedAssignee }));
1270
- const preview = core.bulkUpdateFieldsPreview(updates, ACTIVE_WORKSPACE_ID);
1271
- const changed = [];
1272
- const errors = [];
1273
- for (const skipped of preview.skipped) {
1274
- if (skipped.statusCode >= 400) {
1275
- errors.push({
1276
- index: skipped.index,
1277
- id: skipped.id,
1278
- message: skipped.message,
1279
- statusCode: skipped.statusCode,
1280
- code: skipped.code
1281
- });
1282
- }
1283
- }
1284
- for (const item of preview.toApply) {
1285
- const updated = core.updateTask(item.id, item.fields, ACTIVE_WORKSPACE_ID);
1286
- if (!updated) {
1287
- errors.push({ index: item.index, id: item.id, message: 'Task not found', statusCode: 404, code: 'TASK_NOT_FOUND' });
1288
- continue;
1289
- }
1290
- changed.push({ id: updated.id, assignee: updated.assignee || 'unassigned' });
1291
- }
1292
- const summary = buildBatchSummary({
1293
- operation: 'bulk-assign-tasks',
1294
- total: list.length,
1295
- succeeded: changed.length
1296
- });
1297
- await notifyResourceMutation({
1298
- taskIds: list.filter((id) => typeof id === 'string'),
1299
- includeTasks: true,
1300
- includeStats: true,
1301
- });
1302
- return {
1303
- content: [{
1304
- type: "text",
1305
- text: JSON.stringify({
1306
- success: errors.length === 0,
1307
- summary,
1308
- results: {
1309
- assigned: changed,
1310
- preflight: {
1311
- deduped: preview.deduped,
1312
- skipped_noop: preview.skipped.filter((s) => s.code === 'NO_CHANGES' || s.code === 'DUPLICATE_SUPERSEDED').length
1313
- }
1314
- },
1315
- errors
1316
- }, null, 2)
1317
- }],
1318
- };
1319
- }
1320
- case "archive_task": {
1321
- const { id, status, reason } = args;
1322
- const isCancelled = status === 'cancelled';
1323
- const task = core.archiveTask(id, isCancelled, reason, ACTIVE_WORKSPACE_ID);
1324
- if (!task) {
1325
- throw new Error(`Task ${id} not found`);
1326
- }
1327
- await notifyResourceMutation({
1328
- taskIds: [id],
1329
- includeTasks: true,
1330
- includeStats: true,
1331
- });
1332
- return {
1333
- content: [{ type: "text", text: `Task ${id} archived as ${status}` }],
1334
- };
1335
- }
1336
- case "list_skills": {
1337
- const skills = core.listSpecialists();
1338
- return {
1339
- content: [{ type: "text", text: JSON.stringify(skills, null, 2) }],
1340
- };
1341
- }
1342
- case "get_config": {
1343
- return {
1344
- content: [{
1345
- type: "text",
1346
- text: JSON.stringify({
1347
- categories: core.getCategories(),
1348
- types: core.getTypes(),
1349
- priorities: core.getPriorities(),
1350
- approaches: core.getApproaches(),
1351
- complexities: COMPLEXITY_OPTIONS
1352
- }, null, 2)
1353
- }],
1354
- };
1355
- }
1356
- case "update_categories": {
1357
- const { categories } = args;
1358
- core.updateCategories(categories);
1359
- await notifyResourceMutation({
1360
- includeConfig: true,
1361
- includeTasks: true,
1362
- includeStats: true,
1363
- });
1364
- return {
1365
- content: [{ type: "text", text: "Categories updated" }],
1366
- };
1367
- }
1368
- case "add_comment": {
1369
- const { id, text, author } = args;
1370
- const validation = validateStructuredCommentForAdd(text);
1371
- if (!validation.ok) {
1372
- throw new Error(validation.message);
1373
- }
1374
- const updated = core.addComment(id, text, author, ACTIVE_WORKSPACE_ID);
1375
- if (!updated) {
1376
- throw new Error(`Task ${id} not found`);
1377
- }
1378
- await notifyResourceMutation({
1379
- taskIds: [id],
1380
- includeTasks: true,
1381
- });
1382
- return {
1383
- content: [{ type: "text", text: `Comment added to ${id}` }],
1384
- };
1385
- }
1386
- case "attach_context_file": {
1387
- const { id, path: inputPath, caption } = args;
1388
- if (!id)
1389
- throw new Error("id is required");
1390
- if (!inputPath || typeof inputPath !== 'string')
1391
- throw new Error("path is required");
1392
- const task = core.getTask(id, ACTIVE_WORKSPACE_ID);
1393
- if (!task) {
1394
- throw new Error(`Task ${id} not found`);
1395
- }
1396
- const trimmedPath = inputPath.trim();
1397
- if (!trimmedPath)
1398
- throw new Error("path cannot be empty");
1399
- const now = new Date().toISOString();
1400
- const safeCaption = typeof caption === 'string' && caption.trim().length > 0
1401
- ? caption.trim()
1402
- : undefined;
1403
- const { projectRoot } = core.getPaths();
1404
- const attachment = (() => {
1405
- if (isHttpUrl(trimmedPath)) {
1406
- return {
1407
- path: trimmedPath,
1408
- caption: safeCaption || trimmedPath,
1409
- timestamp: now
1410
- };
1411
- }
1412
- const resolved = path.isAbsolute(trimmedPath)
1413
- ? path.resolve(trimmedPath)
1414
- : path.resolve(projectRoot, trimmedPath);
1415
- if (!fs.existsSync(resolved)) {
1416
- throw new Error(`File not found: ${trimmedPath}`);
1417
- }
1418
- const real = fs.realpathSync(resolved);
1419
- if (!isWithinRoot(real, projectRoot)) {
1420
- throw new Error("Linked file must be within project root");
1421
- }
1422
- if (!fs.statSync(real).isFile()) {
1423
- throw new Error(`Path is not a file: ${trimmedPath}`);
1424
- }
1425
- const relativePath = toPosixPath(path.relative(projectRoot, real));
1426
- if (relativePath.endsWith('.md')) {
1427
- const content = fs.readFileSync(real, 'utf8');
1428
- const validation = validateStructuredDocForAttach(relativePath, content);
1429
- if (!validation.ok) {
1430
- throw new Error(validation.message);
1431
- }
1432
- }
1433
- return {
1434
- path: `/api/taskforce/context-link?path=${encodeURIComponent(relativePath)}`,
1435
- fsPath: relativePath,
1436
- caption: safeCaption || path.basename(real),
1437
- timestamp: now
1438
- };
1439
- })();
1440
- const existing = Array.isArray(task.attachments)
1441
- ? task.attachments
1442
- : (Array.isArray(task.screenshots) ? task.screenshots : []);
1443
- const duplicate = existing.some((item) => {
1444
- if (typeof item === 'string') {
1445
- return item === attachment.path || (!!attachment.fsPath && item === attachment.fsPath);
1446
- }
1447
- if (!item || typeof item !== 'object')
1448
- return false;
1449
- if (item.path === attachment.path)
1450
- return true;
1451
- if (attachment.fsPath && item.fsPath === attachment.fsPath)
1452
- return true;
1453
- return false;
1454
- });
1455
- if (duplicate) {
1456
- return {
1457
- content: [{ type: "text", text: `Context file already attached to ${id}` }],
1458
- };
1459
- }
1460
- const updated = core.updateTask(id, {
1461
- attachments: [...existing, attachment]
1462
- }, ACTIVE_WORKSPACE_ID);
1463
- if (!updated) {
1464
- throw new Error(`Task ${id} not found`);
1465
- }
1466
- await notifyResourceMutation({
1467
- taskIds: [id],
1468
- includeTasks: true,
1469
- });
1470
- return {
1471
- content: [{ type: "text", text: `Attached context file to ${id}\n${JSON.stringify(attachment, null, 2)}` }],
1472
- };
1473
- }
1474
- case "save_task_attachment": {
1475
- const { id, filename, content, sourcePath, caption, overwrite = false } = args;
1476
- if (!id)
1477
- throw new Error("id is required");
1478
- if (!filename || typeof filename !== 'string')
1479
- throw new Error("filename is required");
1480
- const hasContent = typeof content === 'string';
1481
- const hasSourcePath = typeof sourcePath === 'string' && sourcePath.trim().length > 0;
1482
- if (hasContent === hasSourcePath) {
1483
- throw new Error("Provide exactly one of: content or sourcePath");
1484
- }
1485
- const task = core.getTask(id, ACTIVE_WORKSPACE_ID);
1486
- if (!task)
1487
- throw new Error(`Task ${id} not found`);
1488
- const now = new Date().toISOString();
1489
- const safeCaption = typeof caption === 'string' && caption.trim().length > 0
1490
- ? caption.trim()
1491
- : undefined;
1492
- const { projectRoot, taskDataDir } = core.getPaths();
1493
- const taskPathSegment = sanitizeTaskIdForPath(id);
1494
- const attachmentsDir = path.join(taskDataDir, taskPathSegment, 'attachments');
1495
- fs.mkdirSync(attachmentsDir, { recursive: true });
1496
- let safeFilename = sanitizeFilenameForPath(filename);
1497
- let destinationPath = path.join(attachmentsDir, safeFilename);
1498
- if (!overwrite) {
1499
- destinationPath = nextAvailablePath(destinationPath);
1500
- safeFilename = path.basename(destinationPath);
1501
- }
1502
- if (hasContent) {
1503
- fs.writeFileSync(destinationPath, content, 'utf8');
1504
- }
1505
- else {
1506
- const trimmedSource = sourcePath.trim();
1507
- const sourceResolved = path.isAbsolute(trimmedSource)
1508
- ? path.resolve(trimmedSource)
1509
- : path.resolve(projectRoot, trimmedSource);
1510
- if (!fs.existsSync(sourceResolved)) {
1511
- throw new Error(`File not found: ${trimmedSource}`);
1512
- }
1513
- const sourceReal = fs.realpathSync(sourceResolved);
1514
- if (!isWithinRoot(sourceReal, projectRoot)) {
1515
- throw new Error("sourcePath must be within project root");
1516
- }
1517
- if (!fs.statSync(sourceReal).isFile()) {
1518
- throw new Error(`Path is not a file: ${trimmedSource}`);
1519
- }
1520
- fs.copyFileSync(sourceReal, destinationPath);
1521
- }
1522
- const relativePath = toPosixPath(path.relative(projectRoot, destinationPath));
1523
- if (relativePath.endsWith('.md')) {
1524
- const fileContent = fs.readFileSync(destinationPath, 'utf8');
1525
- const validation = validateStructuredDocForAttach(relativePath, fileContent);
1526
- if (!validation.ok) {
1527
- throw new Error(validation.message);
1528
- }
1529
- }
1530
- const attachment = {
1531
- path: `/api/taskforce/context-link?path=${encodeURIComponent(relativePath)}`,
1532
- fsPath: relativePath,
1533
- caption: safeCaption || safeFilename,
1534
- timestamp: now
1535
- };
1536
- const existing = Array.isArray(task.attachments)
1537
- ? task.attachments
1538
- : (Array.isArray(task.screenshots) ? task.screenshots : []);
1539
- const duplicate = existing.some((item) => {
1540
- if (typeof item === 'string') {
1541
- return item === attachment.path || item === attachment.fsPath;
1542
- }
1543
- if (!item || typeof item !== 'object')
1544
- return false;
1545
- if (item.path === attachment.path)
1546
- return true;
1547
- if (item.fsPath === attachment.fsPath)
1548
- return true;
1549
- return false;
1550
- });
1551
- if (duplicate) {
1552
- return {
1553
- content: [{ type: "text", text: `Task attachment saved for ${id}\n${JSON.stringify(attachment, null, 2)}\nAlready attached.` }],
1554
- };
1555
- }
1556
- const updated = core.updateTask(id, {
1557
- attachments: [...existing, attachment]
1558
- }, ACTIVE_WORKSPACE_ID);
1559
- if (!updated) {
1560
- throw new Error(`Task ${id} not found`);
1561
- }
1562
- await notifyResourceMutation({
1563
- taskIds: [id],
1564
- includeTasks: true,
1565
- });
1566
- return {
1567
- content: [{ type: "text", text: `Task attachment saved and attached to ${id}\n${JSON.stringify(attachment, null, 2)}` }],
1568
- };
1569
- }
1570
- case "list_archive": {
1571
- const { format = "markdown" } = args;
1572
- const archive = core.listArchive(ACTIVE_WORKSPACE_ID);
1573
- if (format === "json") {
1574
- return {
1575
- content: [{ type: "text", text: JSON.stringify(archive.archived, null, 2) }],
1576
- };
1577
- }
1578
- return {
1579
- content: [{ type: "text", text: renderTaskTable(archive.archived) }],
1580
- };
1581
- }
1582
- case "unarchive_task": {
1583
- const { id } = args;
1584
- const task = core.unarchiveTask(id, ACTIVE_WORKSPACE_ID);
1585
- if (!task) {
1586
- throw new Error(`Task ${id} not found in archive`);
1587
- }
1588
- await notifyResourceMutation({
1589
- taskIds: [id],
1590
- includeTasks: true,
1591
- includeStats: true,
1592
- });
1593
- return {
1594
- content: [{ type: "text", text: `Task ${id} unarchived` }],
1595
- };
1596
- }
1597
- case "bulk_archive": {
1598
- const { ids, status = "done" } = args;
1599
- const isCancellation = status === "cancelled";
1600
- const list = Array.isArray(ids) ? ids : [];
1601
- const archived = [];
1602
- const errors = [];
1603
- for (let i = 0; i < list.length; i++) {
1604
- const id = list[i];
1605
- try {
1606
- const item = core.archiveTask(id, isCancellation, undefined, ACTIVE_WORKSPACE_ID);
1607
- if (!item) {
1608
- errors.push({ index: i, id, message: 'Task not found', statusCode: 404, code: 'TASK_NOT_FOUND' });
1609
- continue;
1610
- }
1611
- archived.push(item);
1612
- }
1613
- catch (error) {
1614
- errors.push({
1615
- index: i,
1616
- id,
1617
- message: error?.message || 'Failed to archive task',
1618
- statusCode: Number.isFinite(Number(error?.statusCode)) ? Number(error.statusCode) : 400,
1619
- code: typeof error?.code === 'string' ? error.code : undefined
1620
- });
1621
- }
1622
- }
1623
- const summary = buildBatchSummary({
1624
- operation: 'bulk-archive',
1625
- total: list.length,
1626
- succeeded: archived.length
1627
- });
1628
- await notifyResourceMutation({
1629
- taskIds: list,
1630
- includeTasks: true,
1631
- includeStats: true,
1632
- });
1633
- return {
1634
- content: [{
1635
- type: "text",
1636
- text: JSON.stringify({
1637
- success: errors.length === 0,
1638
- summary,
1639
- results: { archived },
1640
- errors
1641
- }, null, 2)
1642
- }],
1643
- };
1644
- }
1645
- case "update_types": {
1646
- const { types } = args;
1647
- core.updateTypes(types);
1648
- await notifyResourceMutation({
1649
- includeConfig: true,
1650
- includeTasks: true,
1651
- includeStats: true,
1652
- });
1653
- return {
1654
- content: [{ type: "text", text: "Task types updated" }],
1655
- };
1656
- }
1657
- case "bulk_update_type": {
1658
- const { fromType, toType } = args;
1659
- const count = core.bulkUpdateType(fromType, toType, ACTIVE_WORKSPACE_ID);
1660
- await notifyResourceMutation({
1661
- includeTasks: true,
1662
- includeStats: true,
1663
- });
1664
- return {
1665
- content: [{ type: "text", text: `Updated ${count} items from ${fromType} to ${toType}` }],
1666
- };
1667
- }
1668
- case "bulk_update_fields": {
1669
- const { updates } = args;
1670
- const list = Array.isArray(updates) ? updates : [];
1671
- // Validate all updates before applying
1672
- for (const update of list) {
1673
- const assigneeInput = update.assignee ?? update.owner;
1674
- update.category = resolveStringOption('category', update.category, core.getCategories().map(c => ({ value: c.value, label: c.label })));
1675
- update.type = resolveStringOption('type', update.type, core.getTypes().map(t => ({ value: t.value, label: t.label })));
1676
- update.priority = resolveNumberOption('priority', update.priority, core.getPriorities().map(p => ({ value: p.value, label: p.label })));
1677
- update.approach = resolveStringOption('approach', update.approach, core.getApproaches().map(a => ({ value: a.value, label: a.label })));
1678
- update.assignee = resolveStringOption('assignee', assigneeInput, [...ASSIGNEE_OPTIONS]);
1679
- delete update.owner;
1680
- update.status = resolveStringOption('status', update.status, STATUS_OPTIONS);
1681
- update.complexity = resolveNumberOption('complexity', update.complexity, COMPLEXITY_OPTIONS);
1682
- }
1683
- const preview = core.bulkUpdateFieldsPreview(list, ACTIVE_WORKSPACE_ID);
1684
- const changed = [];
1685
- const errors = [];
1686
- for (const skipped of preview.skipped) {
1687
- if (skipped.statusCode >= 400) {
1688
- errors.push({
1689
- index: skipped.index,
1690
- id: skipped.id,
1691
- message: skipped.message,
1692
- statusCode: skipped.statusCode,
1693
- code: skipped.code
1694
- });
1695
- }
1696
- }
1697
- for (const item of preview.toApply) {
1698
- const updated = core.updateTask(item.id, item.fields, ACTIVE_WORKSPACE_ID);
1699
- if (!updated) {
1700
- errors.push({ index: item.index, id: item.id, message: 'Task not found', statusCode: 404, code: 'TASK_NOT_FOUND' });
1701
- continue;
1702
- }
1703
- changed.push({ id: item.id, fields: item.changedFields });
1704
- }
1705
- const summary = buildBatchSummary({
1706
- operation: 'bulk-update-fields',
1707
- total: list.length,
1708
- succeeded: changed.length
1709
- });
1710
- await notifyResourceMutation({
1711
- includeTasks: true,
1712
- includeStats: true,
1713
- });
1714
- return {
1715
- content: [{
1716
- type: "text",
1717
- text: JSON.stringify({
1718
- success: errors.length === 0,
1719
- summary,
1720
- results: {
1721
- changes: changed,
1722
- preflight: {
1723
- deduped: preview.deduped,
1724
- skipped_noop: preview.skipped.filter((s) => s.code === 'NO_CHANGES' || s.code === 'DUPLICATE_SUPERSEDED').length,
1725
- by_field: preview.byField,
1726
- priority_before: preview.priorityBefore,
1727
- priority_after: preview.priorityAfter
1728
- }
1729
- },
1730
- errors
1731
- }, null, 2)
1732
- }],
1733
- };
1734
- }
1735
- case "export_resources": {
1736
- const { type, path, variables, environment } = args;
1737
- const count = core.exportResources(type, path, variables, environment);
1738
- return {
1739
- content: [{ type: "text", text: `Exported ${count} ${type} to ${path}` }],
1740
- };
1741
- }
1742
- case "get_paths": {
1743
- const paths = core.getPaths();
1744
- return {
1745
- content: [{ type: "text", text: JSON.stringify(paths, null, 2) }],
1746
- };
1747
- }
1748
- case "update_priorities": {
1749
- const { priorities } = args;
1750
- core.updatePriorities(priorities);
1751
- await notifyResourceMutation({
1752
- includeConfig: true,
1753
- includeTasks: true,
1754
- includeStats: true,
1755
- });
1756
- return {
1757
- content: [{ type: "text", text: "Priorities updated" }],
1758
- };
1759
- }
1760
- case "update_approaches": {
1761
- const { approaches } = args;
1762
- core.updateApproaches(approaches);
1763
- await notifyResourceMutation({
1764
- includeConfig: true,
1765
- includeTasks: true,
1766
- includeStats: true,
1767
- });
1768
- return {
1769
- content: [{ type: "text", text: "Approaches updated" }],
1770
- };
1771
- }
1772
- case "get_stats": {
1773
- const stats = core.getStats(ACTIVE_WORKSPACE_ID);
1774
- return {
1775
- content: [{ type: "text", text: JSON.stringify(stats, null, 2) }],
1776
- };
1777
- }
1778
- default:
1779
- throw new Error(`Unknown tool: ${name}`);
1780
- }
1781
- }
1782
- catch (error) {
1783
- return {
1784
- content: [{ type: "text", text: `Error: ${error.message}` }],
1785
- isError: true,
1786
- };
1787
- }
1788
- });
1789
- /**
1790
- * Start Server
1791
- */
1792
- const transport = new StdioServerTransport();
1793
- await server.connect(transport);
1
+ import { startTaskforceMcpStdioServer } from './runtime.js';
2
+ await startTaskforceMcpStdioServer();