@@ -12,7 +12,6 @@ import { z } from "zod";
12
12
13
13
import { TaskManagerServer } from "./src/server/TaskManagerServer.js" ;
14
14
import { ALL_TOOLS } from "./src/types/tools.js" ;
15
- import { ProjectActionSchema , TaskActionSchema } from "./src/types/index.js" ;
16
15
17
16
const DEFAULT_PATH = path . join ( os . homedir ( ) , "Documents" , "tasks.json" ) ;
18
17
const TASK_FILE_PATH = process . env . TASK_MANAGER_FILE_PATH || DEFAULT_PATH ;
@@ -37,85 +36,217 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
37
36
tools : ALL_TOOLS ,
38
37
} ) ) ;
39
38
40
- // Create specific schemas for CallToolRequestSchema to validate against our tool schemas
41
- const ProjectToolCallSchema = CallToolRequestSchema . extend ( {
42
- params : z . object ( {
43
- name : z . literal ( "project" ) ,
44
- arguments : z . object ( {
45
- action : z . string ( ) ,
46
- arguments : z . any ( )
47
- } )
48
- } )
49
- } ) ;
50
-
51
- const TaskToolCallSchema = CallToolRequestSchema . extend ( {
52
- params : z . object ( {
53
- name : z . literal ( "task" ) ,
54
- arguments : z . object ( {
55
- action : z . string ( ) ,
56
- arguments : z . any ( )
57
- } )
58
- } )
59
- } ) ;
60
-
61
39
server . setRequestHandler ( CallToolRequestSchema , async ( request ) => {
62
40
try {
63
- const { name, arguments : args } = request . params ;
41
+ const { name } = request . params ;
42
+ const args = request . params . arguments || { } ;
43
+
44
+ // For validation, ensure args is an object when expected
45
+ if ( name !== "list_projects" && name !== "list_tasks" && Object . keys ( args ) . length === 0 ) {
46
+ throw new Error ( "Invalid arguments: expected object with parameters" ) ;
47
+ }
64
48
65
49
switch ( name ) {
66
- case "project" : {
67
- // Validate request against the schema
68
- const validationResult = ProjectToolCallSchema . safeParse ( request ) ;
69
- if ( ! validationResult . success ) {
70
- throw new Error ( `Invalid request: ${ validationResult . error . message } ` ) ;
50
+ // Project tools
51
+ case "list_projects" : {
52
+ const result = await taskManagerServer . listProjects ( ) ;
53
+ return {
54
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
55
+ } ;
56
+ }
57
+
58
+ case "read_project" : {
59
+ const projectId = String ( args . projectId ) ;
60
+ if ( ! projectId ) {
61
+ throw new Error ( "Missing required parameter: projectId" ) ;
71
62
}
63
+ const result = await taskManagerServer . getNextTask ( projectId ) ;
64
+ return {
65
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
66
+ } ;
67
+ }
72
68
73
- // Further validate the action and arguments
74
- if ( ! args || typeof args !== 'object' ) {
75
- throw new Error ( "Invalid arguments: expected object" ) ;
69
+ case "create_project" : {
70
+ const initialPrompt = String ( args . initialPrompt || "" ) ;
71
+ if ( ! initialPrompt || ! args . tasks || ! Array . isArray ( args . tasks ) ) {
72
+ throw new Error ( "Missing required parameters: initialPrompt and/or tasks" ) ;
76
73
}
74
+ const projectPlan = args . projectPlan ? String ( args . projectPlan ) : undefined ;
75
+
76
+ const result = await taskManagerServer . createProject (
77
+ initialPrompt ,
78
+ args . tasks ,
79
+ projectPlan
80
+ ) ;
81
+ return {
82
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
83
+ } ;
84
+ }
77
85
78
- const { action, arguments : actionArgs } = args ;
79
- if ( ! action || typeof action !== 'string' ) {
80
- throw new Error ( "Missing or invalid 'action' field" ) ;
86
+ case "delete_project" : {
87
+ const projectId = String ( args . projectId ) ;
88
+ if ( ! projectId ) {
89
+ throw new Error ( "Missing required parameter: projectId" ) ;
90
+ }
91
+ // Use the private data and saveTasks via indexing since there's no explicit delete method
92
+ const projectIndex = taskManagerServer [ "data" ] . projects . findIndex ( ( p ) => p . projectId === projectId ) ;
93
+ if ( projectIndex === - 1 ) {
94
+ return {
95
+ content : [ { type : "text" , text : JSON . stringify ( { status : "error" , message : "Project not found" } , null , 2 ) } ] ,
96
+ } ;
81
97
}
98
+
99
+ taskManagerServer [ "data" ] . projects . splice ( projectIndex , 1 ) ;
100
+ await taskManagerServer [ "saveTasks" ] ( ) ;
101
+ return {
102
+ content : [ { type : "text" , text : JSON . stringify ( {
103
+ status : "project_deleted" ,
104
+ message : `Project ${ projectId } has been deleted.`
105
+ } , null , 2 ) } ] ,
106
+ } ;
107
+ }
82
108
83
- // Validate against the specific action schema
84
- const actionSchema = ProjectActionSchema . safeParse ( { action , arguments : actionArgs } ) ;
85
- if ( ! actionSchema . success ) {
86
- throw new Error ( `Invalid action parameters: ${ actionSchema . error . message } ` ) ;
109
+ case "add_tasks_to_project" : {
110
+ const projectId = String ( args . projectId ) ;
111
+ if ( ! projectId || ! args . tasks || ! Array . isArray ( args . tasks ) ) {
112
+ throw new Error ( "Missing required parameters: projectId and/or tasks" ) ;
87
113
}
114
+ const result = await taskManagerServer . addTasksToProject ( projectId , args . tasks ) ;
115
+ return {
116
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
117
+ } ;
118
+ }
88
119
89
- const result = await taskManagerServer . handleProjectTool ( action , actionArgs ) ;
120
+ case "finalize_project" : {
121
+ const projectId = String ( args . projectId ) ;
122
+ if ( ! projectId ) {
123
+ throw new Error ( "Missing required parameter: projectId" ) ;
124
+ }
125
+ const result = await taskManagerServer . approveProjectCompletion ( projectId ) ;
90
126
return {
91
127
content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
92
128
} ;
93
129
}
94
130
95
- case "task" : {
96
- // Validate request against the schema
97
- const validationResult = TaskToolCallSchema . safeParse ( request ) ;
98
- if ( ! validationResult . success ) {
99
- throw new Error ( `Invalid request: ${ validationResult . error . message } ` ) ;
131
+ // Task tools
132
+ case "list_tasks" : {
133
+ // No explicit list tasks method, so return a message
134
+ return {
135
+ content : [ { type : "text" , text : JSON . stringify ( {
136
+ status : "error" ,
137
+ message : "list_tasks functionality to be implemented in future version"
138
+ } , null , 2 ) } ] ,
139
+ } ;
140
+ }
141
+
142
+ case "read_task" : {
143
+ const taskId = String ( args . taskId ) ;
144
+ if ( ! taskId ) {
145
+ throw new Error ( "Missing required parameter: taskId" ) ;
100
146
}
147
+ const result = await taskManagerServer . openTaskDetails ( taskId ) ;
148
+ return {
149
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
150
+ } ;
151
+ }
101
152
102
- // Further validate the action and arguments
103
- if ( ! args || typeof args !== 'object' ) {
104
- throw new Error ( "Invalid arguments: expected object" ) ;
153
+ case "create_task" : {
154
+ const projectId = String ( args . projectId ) ;
155
+ const title = String ( args . title || "" ) ;
156
+ const description = String ( args . description || "" ) ;
157
+
158
+ if ( ! projectId || ! title || ! description ) {
159
+ throw new Error ( "Missing required parameters: projectId, title, and/or description" ) ;
105
160
}
161
+
162
+ const result = await taskManagerServer . addTasksToProject ( projectId , [ {
163
+ title,
164
+ description
165
+ } ] ) ;
166
+ return {
167
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
168
+ } ;
169
+ }
106
170
107
- const { action, arguments : actionArgs } = args ;
108
- if ( ! action || typeof action !== 'string' ) {
109
- throw new Error ( "Missing or invalid 'action' field" ) ;
171
+ case "update_task" : {
172
+ const projectId = String ( args . projectId ) ;
173
+ const taskId = String ( args . taskId ) ;
174
+
175
+ if ( ! projectId || ! taskId ) {
176
+ throw new Error ( "Missing required parameters: projectId and/or taskId" ) ;
110
177
}
178
+
179
+ const updates : { title ?: string ; description ? : string } = { } ;
180
+ if ( args . title !== undefined ) updates . title = String ( args . title ) ;
181
+ if ( args . description !== undefined ) updates . description = String ( args . description ) ;
182
+
183
+ const result = await taskManagerServer . updateTask ( projectId , taskId , updates ) ;
184
+
185
+ // Handle status change separately if needed
186
+ if ( args . status ) {
187
+ const status = args . status as "not started" | "in progress" | "done" ;
188
+ const proj = taskManagerServer [ "data" ] . projects . find ( p => p . projectId === projectId ) ;
189
+ if ( proj ) {
190
+ const task = proj . tasks . find ( t => t . id === taskId ) ;
191
+ if ( task ) {
192
+ if ( status === "done" ) {
193
+ if ( ! args . completedDetails ) {
194
+ return {
195
+ content : [ { type : "text" , text : JSON . stringify ( {
196
+ status : "error" ,
197
+ message : "completedDetails is required when setting status to 'done'"
198
+ } , null , 2 ) } ] ,
199
+ } ;
200
+ }
201
+
202
+ // Use markTaskDone for proper transition to done status
203
+ await taskManagerServer . markTaskDone ( projectId , taskId , String ( args . completedDetails ) ) ;
204
+ } else {
205
+ // For other status changes
206
+ task . status = status ;
207
+ await taskManagerServer [ "saveTasks" ] ( ) ;
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ return {
214
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
215
+ } ;
216
+ }
111
217
112
- // Validate against the specific action schema
113
- const actionSchema = TaskActionSchema . safeParse ( { action, arguments : actionArgs } ) ;
114
- if ( ! actionSchema . success ) {
115
- throw new Error ( `Invalid action parameters: ${ actionSchema . error . message } ` ) ;
218
+ case "delete_task" : {
219
+ const projectId = String ( args . projectId ) ;
220
+ const taskId = String ( args . taskId ) ;
221
+
222
+ if ( ! projectId || ! taskId ) {
223
+ throw new Error ( "Missing required parameters: projectId and/or taskId" ) ;
116
224
}
225
+ const result = await taskManagerServer . deleteTask ( projectId , taskId ) ;
226
+ return {
227
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
228
+ } ;
229
+ }
117
230
118
- const result = await taskManagerServer . handleTaskTool ( action , actionArgs ) ;
231
+ case "approve_task" : {
232
+ const projectId = String ( args . projectId ) ;
233
+ const taskId = String ( args . taskId ) ;
234
+
235
+ if ( ! projectId || ! taskId ) {
236
+ throw new Error ( "Missing required parameters: projectId and/or taskId" ) ;
237
+ }
238
+ const result = await taskManagerServer . approveTaskCompletion ( projectId , taskId ) ;
239
+ return {
240
+ content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
241
+ } ;
242
+ }
243
+
244
+ case "get_next_task" : {
245
+ const projectId = String ( args . projectId ) ;
246
+ if ( ! projectId ) {
247
+ throw new Error ( "Missing required parameter: projectId" ) ;
248
+ }
249
+ const result = await taskManagerServer . getNextTask ( projectId ) ;
119
250
return {
120
251
content : [ { type : "text" , text : JSON . stringify ( result , null , 2 ) } ] ,
121
252
} ;
0 commit comments