@taskforcehq/taskforce 0.3.323 → 0.3.326

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 (70) hide show
  1. package/dist/Taskforce.module.css +56 -0
  2. package/dist/components/features/TaskSettings.js +26 -9
  3. package/dist/components/task/TaskKanban.d.ts +2 -2
  4. package/dist/components/views/AppShellHeader.js +47 -2
  5. package/dist/components/views/StandaloneLayout.js +22 -22
  6. package/dist/components/views/panels/PlanningDrawer.d.ts +2 -2
  7. package/dist/components/views/panels/PlanningDrawer.js +26 -12
  8. package/dist/components/views/planningScope.d.ts +4 -0
  9. package/dist/components/views/planningScope.js +5 -0
  10. package/dist/core/AiProfileService.js +6 -1
  11. package/dist/core/Taskforce.d.ts +3 -0
  12. package/dist/core/Taskforce.js +21 -0
  13. package/dist/hooks/useTaskforce.js +74 -17
  14. package/dist/hooks/workspace/workspaceLocalState.d.ts +25 -0
  15. package/dist/hooks/workspace/workspaceLocalState.js +38 -0
  16. package/dist/mcp/adminWorkspaceRegistrar.js +0 -10
  17. package/dist/mcp/clientIntegrations.d.ts +1 -1
  18. package/dist/mcp/clientIntegrations.js +50 -0
  19. package/dist/mcp/clientProfileDefaults.js +4 -0
  20. package/dist/mcp/collaborationRegistrar.js +3 -3
  21. package/dist/mcp/documentAssetRegistrar.js +24 -72
  22. package/dist/mcp/documentHelpers.d.ts +11 -4
  23. package/dist/mcp/documentHelpers.js +21 -17
  24. package/dist/mcp/runtime.d.ts +4 -0
  25. package/dist/mcp/runtime.js +466 -534
  26. package/dist/mcp/taskPlanningRegistrar.js +45 -81
  27. package/dist/mcp/toolProfiles.d.ts +7 -0
  28. package/dist/mcp/toolProfiles.js +36 -0
  29. package/dist/mcp/toolRegistry.d.ts +87 -609
  30. package/dist/mcp/toolRegistry.js +93 -88
  31. package/dist/resources/templates/workflow-sources/workflowDocs.mjs +10 -10
  32. package/dist/resources/templates/workflows/collaborate.yaml +2 -3
  33. package/dist/resources/templates/workflows/do.yaml +2 -3
  34. package/dist/resources/templates/workflows/evaluate.yaml +2 -3
  35. package/dist/resources/templates/workflows/execute.yaml +12 -15
  36. package/dist/resources/templates/workflows/plan.yaml +3 -4
  37. package/dist/resources/templates/workflows/review.yaml +2 -3
  38. package/dist/server/routes/admin.d.ts +1 -0
  39. package/dist/server/routes/admin.js +29 -1
  40. package/dist/shared/taxonomyLibrary.js +1 -1
  41. package/dist/sync/cloudSyncApi.js +22 -3
  42. package/dist/types.js +1 -1
  43. package/dist/ui/.well-known/openai-apps-challenge +1 -1
  44. package/dist/ui/assets/{AgentsModule-7jpDeuVR.js → AgentsModule-C4LcqhcZ.js} +1 -1
  45. package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BJLe8DFj.js → AnnotatedAttachmentWorkspace-B-Dq22d2.js} +1 -1
  46. package/dist/ui/assets/{ContextAttachmentManager-AmEny3eI.js → ContextAttachmentManager-DsXPTvi-.js} +1 -1
  47. package/dist/ui/assets/{DocumentWorkspace-Cqdq31Ha.js → DocumentWorkspace-CxA1wO3U.js} +1 -1
  48. package/dist/ui/assets/{EntityActivityTimeline-BlS7DhA4.js → EntityActivityTimeline-B8nSe8l3.js} +1 -1
  49. package/dist/ui/assets/{InitiativesModule-C1qfO1uZ.js → InitiativesModule-VY95v38E.js} +1 -1
  50. package/dist/ui/assets/{PlansPage-DFt5w-0Y.js → PlansPage-CQbKDv1a.js} +1 -1
  51. package/dist/ui/assets/{TaskContextUpload-zuro5gDT.js → TaskContextUpload-DvDlNpHC.js} +1 -1
  52. package/dist/ui/assets/TaskSettings-CUWbYYtP.js +12 -0
  53. package/dist/ui/assets/{WorkflowsModule-CEEGuxsf.js → WorkflowsModule-CgM3Jako.js} +1 -1
  54. package/dist/ui/assets/documentReferences-Do9YjrS3.js +1 -0
  55. package/dist/ui/assets/index--mh3pktj.js +5 -0
  56. package/dist/ui/assets/index-BawaaEXS.css +1 -0
  57. package/dist/ui/index.html +2 -2
  58. package/dist/utils/theme.js +1 -1
  59. package/package.json +1 -1
  60. package/src/resources/templates/workflow-sources/workflowDocs.mjs +10 -10
  61. package/src/resources/templates/workflows/collaborate.yaml +2 -3
  62. package/src/resources/templates/workflows/do.yaml +2 -3
  63. package/src/resources/templates/workflows/evaluate.yaml +2 -3
  64. package/src/resources/templates/workflows/execute.yaml +12 -15
  65. package/src/resources/templates/workflows/plan.yaml +3 -4
  66. package/src/resources/templates/workflows/review.yaml +2 -3
  67. package/dist/ui/assets/TaskSettings-CJPC2Bft.js +0 -9
  68. package/dist/ui/assets/documentReferences-Ca2P--i5.js +0 -1
  69. package/dist/ui/assets/index-CGDQY0nN.js +0 -5
  70. package/dist/ui/assets/index-DcK_8tuE.css +0 -1
@@ -2,6 +2,15 @@ import { bindDomainTool } from './toolCatalog.js';
2
2
  function stringProperty(description, enumValues) {
3
3
  return enumValues ? { type: 'string', description, enum: enumValues } : { type: 'string', description };
4
4
  }
5
+ function nullableStringProperty(description) {
6
+ return {
7
+ description,
8
+ anyOf: [
9
+ { type: 'string' },
10
+ { type: 'null' },
11
+ ],
12
+ };
13
+ }
5
14
  function numberProperty(description) {
6
15
  return { type: 'number', description };
7
16
  }
@@ -58,7 +67,7 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
58
67
  },
59
68
  }));
60
69
  register('get_task', (context) => ({
61
- description: context.describeTool('Get a single task by ID or task reference. Checks both active and archived tasks. Use this when you have a specific task ID or T-123 reference from a previous list or search result and need full details including comments and attachment metadata. This tool does not return attachment file contents. For task attachments, call get_task_attachments and then read_task_attachment. Do not fetch attachment path URLs directly when MCP attachment-read tools are available. Do not use this for image references like I-123 or document references like D-123.'),
70
+ description: context.describeTool('Get one task by ID or T-123 reference, including comments, activity, checklist, links, and attachment metadata. Use get_task_attachments for attachment bodies; use D-123/I-123 tools for documents/images.'),
62
71
  inputSchema: {
63
72
  properties: {
64
73
  id: stringProperty('Task ID or task reference such as T-123.'),
@@ -228,42 +237,24 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
228
237
  required: ['id'],
229
238
  },
230
239
  }));
231
- register('set_task_workstream', (context) => ({
232
- description: context.describeTool('Assign an existing task to a workstream. Reassigning a task removes it from any previous workstream.'),
240
+ register('update_task_workstream', (context) => ({
241
+ description: context.describeTool('Set or clear the workstream for one task. Pass workstreamId to assign or reassign; pass an empty string or null to unlink the task from its current workstream.'),
233
242
  inputSchema: {
234
243
  properties: {
235
244
  taskId: stringProperty('Task ID or task reference such as T-123.'),
236
- workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
237
- },
238
- required: ['taskId', 'workstreamId'],
239
- },
240
- }));
241
- register('clear_task_workstream', (context) => ({
242
- description: context.describeTool('Remove a task from its current workstream, making it standalone.'),
243
- inputSchema: {
244
- properties: {
245
- taskId: stringProperty('Task ID or task reference such as T-123.'),
246
- },
247
- required: ['taskId'],
248
- },
249
- }));
250
- register('set_workstream_initiative', (context) => ({
251
- description: context.describeTool('Assign an existing workstream to an initiative. Reassigning a workstream removes it from any previous initiative.'),
252
- inputSchema: {
253
- properties: {
254
- workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
255
- initiativeId: stringProperty('Initiative ID or initiative reference such as IN-123.'),
245
+ id: stringProperty('Alias for taskId. Task ID or task reference such as T-123.'),
246
+ workstreamId: nullableStringProperty('Workstream ID or workstream reference such as WS-123. Pass an empty string or null to unlink.'),
256
247
  },
257
- required: ['workstreamId', 'initiativeId'],
258
248
  },
259
249
  }));
260
- register('clear_workstream_initiative', (context) => ({
261
- description: context.describeTool('Remove a workstream from its current initiative, making it standalone.'),
250
+ register('update_workstream_initiative', (context) => ({
251
+ description: context.describeTool('Set or clear the initiative for one workstream. Pass initiativeId to assign or reassign; pass an empty string or null to unlink the workstream from its current initiative.'),
262
252
  inputSchema: {
263
253
  properties: {
264
254
  workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
255
+ id: stringProperty('Alias for workstreamId. Workstream ID or workstream reference such as WS-123.'),
256
+ initiativeId: nullableStringProperty('Initiative ID or initiative reference such as IN-123. Pass an empty string or null to unlink.'),
265
257
  },
266
- required: ['workstreamId'],
267
258
  },
268
259
  }));
269
260
  register('get_task_checklist', (context) => ({
@@ -293,41 +284,42 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
293
284
  },
294
285
  }));
295
286
  register('get_schedule_board', (context) => ({
296
- description: context.describeTool('Read the current schedule board for the active workspace. Use this before scheduling or reordering tasks when you need the existing day layout and order.'),
287
+ description: context.describeTool('Read the current schedule board for the active workspace. Use this before scheduling tasks when you need the existing day layout and order.'),
297
288
  inputSchema: { properties: {} },
298
289
  }));
299
- register('schedule_task', (context) => ({
300
- description: context.describeTool('Schedule a task on a specific day. Use get_schedule_board first when you need the current order before inserting the task.'),
290
+ register('update_schedule', (context) => ({
291
+ description: context.describeTool('Default schedule write path. Schedule, unschedule, or reorder scheduled tasks. Pass taskId with date to schedule, taskId with date=null or an empty string to unschedule, or pass date plus taskIds to replace one day order. Use get_schedule_board first when you need the current board state.'),
301
292
  inputSchema: {
302
293
  properties: {
303
294
  taskId: stringProperty('Task ID or task reference such as T-123.'),
304
- date: stringProperty('Target date in YYYY-MM-DD format.'),
295
+ id: stringProperty('Alias for taskId. Task ID or task reference such as T-123.'),
296
+ date: nullableStringProperty('Target date in YYYY-MM-DD format. Pass an empty string or null with taskId to unschedule.'),
297
+ scheduledDate: nullableStringProperty('Alias for date. Target date in YYYY-MM-DD format. Pass an empty string or null with taskId to unschedule.'),
305
298
  order: numberProperty('Optional position within that day.'),
299
+ orderInDay: numberProperty('Alias for order. Optional position within that day.'),
300
+ taskIds: arrayProperty('Ordered task IDs or task references for replacing one scheduled day order.', { type: 'string' }),
301
+ moves: arrayProperty('Advanced reorder moves. Each move may include id or taskId, date or scheduledDate, and order or orderInDay.', {
302
+ type: 'object',
303
+ properties: {
304
+ id: { type: 'string' },
305
+ taskId: { type: 'string' },
306
+ date: { type: 'string' },
307
+ scheduledDate: { type: 'string' },
308
+ order: { type: 'number' },
309
+ orderInDay: { type: 'number' },
310
+ },
311
+ anyOf: [
312
+ { required: ['id', 'date'] },
313
+ { required: ['id', 'scheduledDate'] },
314
+ { required: ['taskId', 'date'] },
315
+ { required: ['taskId', 'scheduledDate'] },
316
+ ],
317
+ }),
306
318
  },
307
- required: ['taskId', 'date'],
308
- },
309
- }));
310
- register('unschedule_task', (context) => ({
311
- description: context.describeTool('Remove a task from the schedule board and return it to the unscheduled pool.'),
312
- inputSchema: {
313
- properties: {
314
- taskId: stringProperty('Task ID or task reference such as T-123.'),
315
- },
316
- required: ['taskId'],
317
- },
318
- }));
319
- register('reorder_scheduled_tasks', (context) => ({
320
- description: context.describeTool('Replace the ordered task list for one scheduled day. Use get_schedule_board first to inspect the current day contents.'),
321
- inputSchema: {
322
- properties: {
323
- date: stringProperty('Target date in YYYY-MM-DD format.'),
324
- taskIds: arrayProperty('Ordered task IDs or task references for that day.', { type: 'string' }),
325
- },
326
- required: ['date', 'taskIds'],
327
319
  },
328
320
  }));
329
321
  register('bulk_carryover', (context) => ({
330
- description: context.describeTool('Carry unfinished scheduled tasks forward from one day to another in bulk.'),
322
+ description: context.describeTool('Extended precision tool for carrying unfinished scheduled tasks forward from one day or week to another in bulk. Use get_schedule_board first to inspect the source period.'),
331
323
  inputSchema: {
332
324
  properties: {
333
325
  fromDate: stringProperty('Source date in YYYY-MM-DD format.'),
@@ -353,7 +345,7 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
353
345
  title: stringProperty('Task title.'),
354
346
  description: stringProperty('Optional task description.'),
355
347
  assignee: stringProperty(`${context.assigneeHint} Call list_assignees to inspect the current eligible IDs.`),
356
- workstreamId: stringProperty('Optional workstream ID or workstream reference such as WS-123. Use this to create the task directly inside a workstream without a separate set_task_workstream call.'),
348
+ workstreamId: stringProperty('Optional workstream ID or workstream reference such as WS-123. Use this to create the task directly inside a workstream without a separate update_task_workstream call.'),
357
349
  category: stringProperty('Task category value.'),
358
350
  type: stringProperty('Task type value.', context.typeEnum),
359
351
  priority: numberProperty(context.priorityDesc),
@@ -406,26 +398,6 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
406
398
  required: ['id'],
407
399
  },
408
400
  }));
409
- register('assign_task', (context) => ({
410
- description: context.describeTool('Assign a task to one eligible assignee. For assigning 3 or more tasks at once, use bulk_assign_tasks instead.'),
411
- inputSchema: {
412
- properties: {
413
- id: stringProperty('Task ID or task reference such as T-123.'),
414
- assignee: stringProperty(`${context.assigneeHint} Call list_assignees to inspect the current eligible IDs.`),
415
- },
416
- required: ['id', 'assignee'],
417
- },
418
- }));
419
- register('bulk_assign_tasks', (context) => ({
420
- description: context.describeTool('Assign multiple tasks to the same eligible assignee in one request. Preferred over repeated assign_task calls when changing 3 or more tasks at once.'),
421
- inputSchema: {
422
- properties: {
423
- ids: arrayProperty('Task IDs or task references such as T-123.', { type: 'string' }),
424
- assignee: stringProperty(`${context.assigneeHint} Call list_assignees to inspect the current eligible IDs.`),
425
- },
426
- required: ['ids', 'assignee'],
427
- },
428
- }));
429
401
  register('archive_task', (context) => ({
430
402
  description: context.describeTool('Move a task to history by archiving it. Use status=\'done\' for completed work or status=\'cancelled\' for abandoned work. active tasks may still use status=done for final lookover without being archived.'),
431
403
  inputSchema: {
@@ -437,14 +409,6 @@ export function registerTaskPlanningTools(registerTool, executeTool) {
437
409
  required: ['id', 'status'],
438
410
  },
439
411
  }));
440
- register('list_archive', (context) => ({
441
- description: context.describeTool('List archived tasks. Use format=json for programmatic use.'),
442
- inputSchema: {
443
- properties: {
444
- format: stringProperty('Toggle output format (default: markdown).', ['markdown', 'json']),
445
- },
446
- },
447
- }));
448
412
  register('unarchive_task', (context) => ({
449
413
  description: context.describeTool('Restore an archived task to the active task list.'),
450
414
  inputSchema: {
@@ -0,0 +1,7 @@
1
+ import { type McpToolName, type McpToolProfile, type McpToolSuccessor } from './toolRegistry.js';
2
+ export declare function normalizeMcpToolProfile(value: unknown, fallback: McpToolProfile): McpToolProfile;
3
+ export declare function getDefaultMcpToolProfile(runtimeMode: 'local' | 'cloud'): McpToolProfile;
4
+ export declare function isMcpToolVisibleInProfile(name: string, profile: McpToolProfile): boolean;
5
+ export declare function getMcpToolRequiredProfiles(name: string): McpToolProfile[];
6
+ export declare function getMcpToolProfileMembership(profile: McpToolProfile): McpToolName[];
7
+ export declare function getMcpToolSuccessor(name: string): McpToolSuccessor | null;
@@ -0,0 +1,36 @@
1
+ import { MCP_TOOL_PROFILES, MCP_TOOL_REGISTRY, } from './toolRegistry.js';
2
+ const PROFILE_RANK = {
3
+ default: 0,
4
+ extended: 1,
5
+ full: 2,
6
+ };
7
+ export function normalizeMcpToolProfile(value, fallback) {
8
+ const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
9
+ return MCP_TOOL_PROFILES.includes(normalized)
10
+ ? normalized
11
+ : fallback;
12
+ }
13
+ export function getDefaultMcpToolProfile(runtimeMode) {
14
+ return runtimeMode === 'cloud' ? 'default' : 'full';
15
+ }
16
+ export function isMcpToolVisibleInProfile(name, profile) {
17
+ const entry = MCP_TOOL_REGISTRY[name];
18
+ if (!entry)
19
+ return false;
20
+ return PROFILE_RANK[profile] >= PROFILE_RANK[entry.minProfile];
21
+ }
22
+ export function getMcpToolRequiredProfiles(name) {
23
+ const entry = MCP_TOOL_REGISTRY[name];
24
+ if (!entry)
25
+ return [];
26
+ return MCP_TOOL_PROFILES.filter((profile) => PROFILE_RANK[profile] >= PROFILE_RANK[entry.minProfile]);
27
+ }
28
+ export function getMcpToolProfileMembership(profile) {
29
+ return Object.entries(MCP_TOOL_REGISTRY)
30
+ .filter(([name]) => isMcpToolVisibleInProfile(name, profile))
31
+ .map(([name]) => name)
32
+ .sort((left, right) => left.localeCompare(right));
33
+ }
34
+ export function getMcpToolSuccessor(name) {
35
+ return MCP_TOOL_REGISTRY[name]?.suggestedTool || null;
36
+ }