@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
@@ -31,44 +31,27 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
31
31
  });
32
32
  };
33
33
  register('get_task_attachments', (context) => ({
34
- description: context.describeTool('List attachment descriptors for one task. This returns metadata only; use read_task_attachment for file contents. For canonical documents, prefer get_document and read_document_content for the document-focused workflow.'),
34
+ description: context.describeTool('List attachment descriptors for one task. Pass attachmentId when you need one attachment body or download reference. For canonical documents, prefer get_document with includeContent=true for the document-focused workflow.'),
35
35
  inputSchema: {
36
36
  properties: {
37
37
  taskId: stringProperty('Task ID or task reference such as T-123.'),
38
38
  id: stringProperty('Alias for taskId. Task ID or task reference such as T-123.'),
39
- },
40
- },
41
- }));
42
- register('read_task_attachment', (context) => ({
43
- description: context.describeTool('Read one task attachment by attachmentId. Prefer this tool over opening attachment path URLs directly. For a canonical document attachment, this response also points toward the document-specific workflow.'),
44
- inputSchema: {
45
- properties: {
46
- taskId: stringProperty('Task ID or task reference such as T-123.'),
47
- attachmentId: stringProperty('Attachment descriptor id from get_task_attachments.'),
39
+ attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
40
+ format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
48
41
  maxChars: numberProperty('Optional max inline character count for readable text attachments.'),
49
42
  },
50
- required: ['taskId', 'attachmentId'],
51
43
  },
52
44
  }));
53
45
  register('get_workstream_attachments', (context) => ({
54
- description: context.describeTool('List attachment descriptors for one workstream. This returns metadata only; use read_workstream_attachment for file contents.'),
46
+ description: context.describeTool('List attachment descriptors for one workstream. Pass attachmentId when you need one attachment body or download reference.'),
55
47
  inputSchema: {
56
48
  properties: {
57
49
  id: stringProperty('Workstream ID or workstream reference such as WS-123.'),
58
- },
59
- required: ['id'],
60
- },
61
- }));
62
- register('read_workstream_attachment', (context) => ({
63
- description: context.describeTool('Read one workstream attachment by attachmentId. Prefer this tool over opening attachment path URLs directly.'),
64
- inputSchema: {
65
- properties: {
66
- workstreamId: stringProperty('Workstream ID or workstream reference such as WS-123.'),
67
- attachmentId: stringProperty('Attachment descriptor id from get_workstream_attachments.'),
68
- format: stringProperty('Read format. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
50
+ attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
51
+ format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
69
52
  maxChars: numberProperty('Optional max inline character count for readable text attachments.'),
70
53
  },
71
- required: ['workstreamId', 'attachmentId'],
54
+ required: ['id'],
72
55
  },
73
56
  }));
74
57
  register('save_workstream_attachment', (context) => ({
@@ -96,24 +79,15 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
96
79
  },
97
80
  }));
98
81
  register('get_initiative_attachments', (context) => ({
99
- description: context.describeTool('List attachment descriptors for one initiative. This returns metadata only; use read_initiative_attachment for file contents.'),
82
+ description: context.describeTool('List attachment descriptors for one initiative. Pass attachmentId when you need one attachment body or download reference.'),
100
83
  inputSchema: {
101
84
  properties: {
102
85
  id: stringProperty('Initiative ID or initiative reference such as IN-123.'),
103
- },
104
- required: ['id'],
105
- },
106
- }));
107
- register('read_initiative_attachment', (context) => ({
108
- description: context.describeTool('Read one initiative attachment by attachmentId. Prefer this tool over opening attachment path URLs directly.'),
109
- inputSchema: {
110
- properties: {
111
- initiativeId: stringProperty('Initiative ID or initiative reference such as IN-123.'),
112
- attachmentId: stringProperty('Attachment descriptor id from get_initiative_attachments.'),
113
- format: stringProperty('Read format. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
86
+ attachmentId: stringProperty('Optional attachment descriptor id to include content for one attachment.'),
87
+ format: stringProperty('Optional read format when attachmentId is provided. Use metadata for descriptors or download for a download URL.', ['text', 'metadata', 'download']),
114
88
  maxChars: numberProperty('Optional max inline character count for readable text attachments.'),
115
89
  },
116
- required: ['initiativeId', 'attachmentId'],
90
+ required: ['id'],
117
91
  },
118
92
  }));
119
93
  register('save_initiative_attachment', (context) => ({
@@ -151,7 +125,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
151
125
  },
152
126
  }));
153
127
  register('get_image', (context) => ({
154
- description: context.describeTool('Get a single image by asset id or image reference such as I-123. Use this first when the user references an image, then use get_annotated_attachment_sessions and read_annotated_attachment_payload for annotation details. When the image is being used for UI, placement, or visual correction feedback, read the saved annotation payload before making changes.'),
128
+ description: context.describeTool('Get a single image by asset id or image reference such as I-123. Use this first when the user references an image, then use get_image_annotations for saved annotation sessions and payloads. When the image is being used for UI, placement, or visual correction feedback, read the saved annotation payload before making changes.'),
155
129
  inputSchema: {
156
130
  properties: {
157
131
  id: stringProperty('Image asset id or image reference such as I-123.'),
@@ -160,7 +134,7 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
160
134
  },
161
135
  }));
162
136
  register('search_documents', (context) => ({
163
- description: context.describeTool('Search document assets by keyword, title, filename, caption, or D-123 reference. Use this before get_document when you only know a rough identifier. Search results guide the next step into get_document and read_document_content.'),
137
+ description: context.describeTool('Search document assets by keyword, title, filename, caption, or D-123 reference. Use this before get_document when you only know a rough identifier. Search results guide the next step into get_document.'),
164
138
  inputSchema: {
165
139
  properties: {
166
140
  query: stringProperty('Search term for document lookup, including D-123 references.'),
@@ -170,40 +144,26 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
170
144
  },
171
145
  }));
172
146
  register('get_document', (context) => ({
173
- description: context.describeTool('Get a single canonical document by asset id or document reference such as D-123. Use this first when the user references a document, then call read_document_content to inspect what it is reviewing.'),
147
+ description: context.describeTool('Get a single canonical document by asset id or document reference such as D-123. Pass includeContent=true when you need the document body for review or analysis.'),
174
148
  inputSchema: {
175
149
  properties: {
176
150
  id: stringProperty('Document asset id or document reference such as D-123.'),
177
151
  documentId: stringProperty('Alias for id. Document asset id or document reference such as D-123.'),
178
- },
179
- },
180
- }));
181
- register('read_document_content', (context) => ({
182
- description: context.describeTool('Read the canonical document body for one document. Use this when an AI needs to inspect what it is reviewing before adding review comments.'),
183
- inputSchema: {
184
- properties: {
185
- documentId: stringProperty('Document asset id or document reference such as D-123.'),
152
+ includeContent: booleanProperty('When true, include bounded inline text content or a download reference for binary documents.'),
153
+ format: stringProperty('Optional read mode when including content.', ['metadata', 'text', 'content', 'full', 'download']),
186
154
  maxChars: numberProperty('Optional max inline character count for readable documents.'),
187
155
  },
188
- required: ['documentId'],
189
156
  },
190
157
  }));
191
- register('get_annotated_attachment_sessions', (context) => ({
192
- description: context.describeTool('List saved annotation sessions for one image. Use this after get_image when you need the saved annotation sessions before opening one payload. If the user is pointing at a visual target in I-123, do not stop at the screenshot alone; inspect the saved session payload next.'),
158
+ register('get_image_annotations', (context) => ({
159
+ description: context.describeTool('List saved annotation sessions for one image or task, and optionally include one session payload. Use this after get_image when an image reference such as I-123 is being used for UI, placement, or visual correction feedback. Pass sessionId when you need the authoritative payload for a specific saved session.'),
193
160
  inputSchema: {
194
161
  properties: {
195
162
  imageId: stringProperty('Image asset id or image reference such as I-123.'),
163
+ imageAssetId: stringProperty('Alias for imageId. Image asset id or image reference such as I-123.'),
164
+ taskId: stringProperty('Optional task ID or task reference such as T-123 to narrow sessions linked to one task.'),
165
+ sessionId: stringProperty('Optional annotated attachment session id to include the structured payload for one session.'),
196
166
  },
197
- required: ['imageId'],
198
- },
199
- }));
200
- register('read_annotated_attachment_payload', (context) => ({
201
- description: context.describeTool('Read the structured payload for one annotated attachment session, including markers, geometry, and derived crop hints. Use this as the authoritative instruction source when I-123 is being used for UI placement or visual change requests.'),
202
- inputSchema: {
203
- properties: {
204
- sessionId: stringProperty('Annotated attachment session id.'),
205
- },
206
- required: ['sessionId'],
207
167
  },
208
168
  }));
209
169
  register('create_annotated_attachment_session', (context) => ({
@@ -320,22 +280,14 @@ export function registerDocumentAssetTools(registerTool, executeTool) {
320
280
  required: ['sessionId', 'markerId'],
321
281
  },
322
282
  }));
323
- register('get_document_review_sessions', (context) => ({
324
- description: context.describeTool('List review sessions for one document such as D-123. Use read_document_content first when you need to inspect the document body before choosing a session.'),
283
+ register('get_document_reviews', (context) => ({
284
+ description: context.describeTool('List review sessions for one document such as D-123, or fetch one review session by sessionId. Use get_document with includeContent=true when you need the document body before choosing a session.'),
325
285
  inputSchema: {
326
286
  properties: {
327
287
  documentId: stringProperty('Document asset id or document reference such as D-123.'),
328
- },
329
- required: ['documentId'],
330
- },
331
- }));
332
- register('get_document_review_session', (context) => ({
333
- description: context.describeTool('Get one document review session with its comments and summary state.'),
334
- inputSchema: {
335
- properties: {
288
+ id: stringProperty('Alias for documentId. Document asset id or document reference such as D-123.'),
336
289
  sessionId: stringProperty('Document review session id.'),
337
290
  },
338
- required: ['sessionId'],
339
291
  },
340
292
  }));
341
293
  register('create_document_review_session', (context) => ({
@@ -47,13 +47,16 @@ export declare function createDocumentHelpers(deps: DocumentHelpersDeps): {
47
47
  nextTool: string;
48
48
  suggestedArgs: {
49
49
  documentId: string;
50
+ includeContent: boolean;
50
51
  };
51
52
  guidance: string;
52
53
  reviewNext: {
53
54
  helperTool: string;
54
55
  listTool: string;
55
- createTool: string;
56
- commentTool: string;
56
+ extendedTools: {
57
+ createTool: string;
58
+ commentTool: string;
59
+ };
57
60
  guidance: string;
58
61
  };
59
62
  reason?: undefined;
@@ -62,13 +65,16 @@ export declare function createDocumentHelpers(deps: DocumentHelpersDeps): {
62
65
  nextTool: string;
63
66
  suggestedArgs: {
64
67
  documentId: string;
68
+ includeContent: boolean;
65
69
  };
66
70
  guidance: string;
67
71
  reviewNext: {
68
72
  helperTool: string;
69
73
  listTool: string;
70
- createTool: string;
71
- commentTool: string;
74
+ extendedTools: {
75
+ createTool: string;
76
+ commentTool: string;
77
+ };
72
78
  guidance: string;
73
79
  };
74
80
  reason: string;
@@ -84,6 +90,7 @@ export declare function createDocumentHelpers(deps: DocumentHelpersDeps): {
84
90
  preferredWorkflow: string;
85
91
  suggestedArgs: {
86
92
  documentId: string;
93
+ includeContent: boolean;
87
94
  };
88
95
  guidance: string;
89
96
  } | null;
@@ -21,29 +21,33 @@ export function createDocumentHelpers(deps) {
21
21
  if (readable) {
22
22
  return {
23
23
  available: true,
24
- nextTool: 'read_document_content',
25
- suggestedArgs: { documentId: preferredIdentifier },
26
- guidance: 'To read the document body, call read_document_content with this documentId.',
24
+ nextTool: 'get_document',
25
+ suggestedArgs: { documentId: preferredIdentifier, includeContent: true },
26
+ guidance: 'To read the document body, call get_document with includeContent=true.',
27
27
  reviewNext: {
28
28
  helperTool: 'review_document',
29
- listTool: 'get_document_review_sessions',
30
- createTool: 'create_document_review_session',
31
- commentTool: 'add_document_review_comment',
32
- guidance: 'After reading the document body, prefer review_document for a lower-friction review flow, or use get_document_review_sessions/create_document_review_session and add_document_review_comment directly.'
29
+ listTool: 'get_document_reviews',
30
+ extendedTools: {
31
+ createTool: 'create_document_review_session',
32
+ commentTool: 'add_document_review_comment',
33
+ },
34
+ guidance: 'After reading the document body, use review_document for default-profile review comments. Use get_document_reviews to inspect saved sessions; extended-profile clients may manage sessions and comments manually.'
33
35
  }
34
36
  };
35
37
  }
36
38
  return {
37
39
  available: false,
38
- nextTool: 'read_document_content',
39
- suggestedArgs: { documentId: preferredIdentifier },
40
- guidance: 'This document is not inline-readable as text. Call read_document_content to get the structured download/reference response.',
40
+ nextTool: 'get_document',
41
+ suggestedArgs: { documentId: preferredIdentifier, includeContent: true },
42
+ guidance: 'This document is not inline-readable as text. Call get_document with includeContent=true to get the structured download/reference response.',
41
43
  reviewNext: {
42
44
  helperTool: 'review_document',
43
- listTool: 'get_document_review_sessions',
44
- createTool: 'create_document_review_session',
45
- commentTool: 'add_document_review_comment',
46
- guidance: 'After inspecting the document access response, prefer review_document for a lower-friction review flow, or use get_document_review_sessions/create_document_review_session and add_document_review_comment directly.'
45
+ listTool: 'get_document_reviews',
46
+ extendedTools: {
47
+ createTool: 'create_document_review_session',
48
+ commentTool: 'add_document_review_comment',
49
+ },
50
+ guidance: 'After inspecting the document access response, use review_document for default-profile review comments. Use get_document_reviews to inspect saved sessions; extended-profile clients may manage sessions and comments manually.'
47
51
  },
48
52
  reason: 'binary_file',
49
53
  };
@@ -60,10 +64,10 @@ export function createDocumentHelpers(deps) {
60
64
  documentId: typeof asset.documentId === 'string' && asset.documentId.trim().length > 0 ? asset.documentId.trim() : null,
61
65
  preferredNextTool: 'get_document',
62
66
  preferredWorkflow: 'canonical_document',
63
- suggestedArgs: { documentId: preferredIdentifier },
67
+ suggestedArgs: { documentId: preferredIdentifier, includeContent: readable },
64
68
  guidance: readable
65
- ? 'This attachment is a canonical document. Prefer get_document, then read_document_content, for ongoing document work and review.'
66
- : 'This attachment is a canonical document. Prefer get_document for metadata and review context, then read_document_content for the structured content/download response.',
69
+ ? 'This attachment is a canonical document. Prefer get_document with includeContent=true for ongoing document work and review.'
70
+ : 'This attachment is a canonical document. Prefer get_document for metadata and review context, then use includeContent=true for the structured content/download response.',
67
71
  };
68
72
  };
69
73
  const searchDocumentAssets = (queryRaw, options) => {
@@ -3,6 +3,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
3
3
  import { McpAccessTokenScope, TaskforceCore } from '../core/Taskforce.js';
4
4
  import { type AiProfileBootstrapConfig } from './aiProfileBootstrap.js';
5
5
  import { type AiProfileSeatScope } from '../shared/aiProfileSeatScope.js';
6
+ import { type McpToolProfile } from './toolRegistry.js';
6
7
  export interface TaskforceMcpServerOptions {
7
8
  projectRoot?: string;
8
9
  tenantId?: string;
@@ -12,6 +13,7 @@ export interface TaskforceMcpServerOptions {
12
13
  version?: string;
13
14
  logStartup?: boolean;
14
15
  runtimeMode?: 'local' | 'cloud';
16
+ toolProfile?: McpToolProfile;
15
17
  auth?: {
16
18
  scopes?: McpAccessTokenScope[] | null;
17
19
  userId?: string | null;
@@ -80,6 +82,7 @@ export declare function createTaskforceMcpServer(options?: TaskforceMcpServerOpt
80
82
  workspaceId: string;
81
83
  tenantId: string;
82
84
  version: string;
85
+ toolProfile: "default" | "full" | "extended";
83
86
  };
84
87
  export declare function startTaskforceMcpStdioServer(options?: TaskforceMcpServerOptions): Promise<{
85
88
  transport: StdioServerTransport;
@@ -123,4 +126,5 @@ export declare function startTaskforceMcpStdioServer(options?: TaskforceMcpServe
123
126
  workspaceId: string;
124
127
  tenantId: string;
125
128
  version: string;
129
+ toolProfile: "default" | "full" | "extended";
126
130
  }>;