├── .gitignore ├── LICENSE ├── README.md ├── biome.json ├── index.ts ├── package-lock.json ├── package.json ├── pnpm-lock.yaml └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 kazuph 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MCP TaskManager 2 | 3 | Model Context Protocol server for Task Management. This allows Claude Desktop (or any MCP client) to manage and execute tasks in a queue-based system. 4 | 5 | @kazuph/mcp-taskmanager MCP server 6 | 7 | ## Quick Start (For Users) 8 | 9 | ### Prerequisites 10 | - Node.js 18+ (install via `brew install node`) 11 | - Claude Desktop (install from https://claude.ai/desktop) 12 | 13 | ### Configuration 14 | 15 | 1. Open your Claude Desktop configuration file at: 16 | `~/Library/Application Support/Claude/claude_desktop_config.json` 17 | 18 | You can find this through the Claude Desktop menu: 19 | 1. Open Claude Desktop 20 | 2. Click Claude on the Mac menu bar 21 | 3. Click "Settings" 22 | 4. Click "Developer" 23 | 24 | 2. Add the following to your configuration: 25 | 26 | ```json 27 | { 28 | "tools": { 29 | "taskmanager": { 30 | "command": "npx", 31 | "args": ["-y", "@kazuph/mcp-taskmanager"] 32 | } 33 | } 34 | } 35 | ``` 36 | 37 | ## For Developers 38 | 39 | ### Prerequisites 40 | - Node.js 18+ (install via `brew install node`) 41 | - Claude Desktop (install from https://claude.ai/desktop) 42 | - tsx (install via `npm install -g tsx`) 43 | 44 | ### Installation 45 | 46 | ```bash 47 | git clone https://github.com/kazuph/mcp-taskmanager.git 48 | cd mcp-taskmanager 49 | npm install 50 | npm run build 51 | ``` 52 | 53 | ### Development Configuration 54 | 55 | 1. Make sure Claude Desktop is installed and running. 56 | 57 | 2. Install tsx globally if you haven't: 58 | ```bash 59 | npm install -g tsx 60 | # or 61 | pnpm add -g tsx 62 | ``` 63 | 64 | 3. Modify your Claude Desktop config located at: 65 | `~/Library/Application Support/Claude/claude_desktop_config.json` 66 | 67 | Add the following to your MCP client's configuration: 68 | 69 | ```json 70 | { 71 | "tools": { 72 | "taskmanager": { 73 | "args": ["tsx", "/path/to/mcp-taskmanager/index.ts"] 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | ## Available Operations 80 | 81 | The TaskManager supports two main phases of operation: 82 | 83 | ### Planning Phase 84 | - Accepts a task list (array of strings) from the user 85 | - Stores tasks internally as a queue 86 | - Returns an execution plan (task overview, task ID, current queue status) 87 | 88 | ### Execution Phase 89 | - Returns the next task from the queue when requested 90 | - Provides feedback mechanism for task completion 91 | - Removes completed tasks from the queue 92 | - Prepares the next task for execution 93 | 94 | ### Parameters 95 | 96 | - `action`: "plan" | "execute" | "complete" 97 | - `tasks`: Array of task strings (required for "plan" action) 98 | - `taskId`: Task identifier (required for "complete" action) 99 | - `getNext`: Boolean flag to request next task (for "execute" action) 100 | 101 | ## Example Usage 102 | 103 | ```typescript 104 | // Planning phase 105 | { 106 | action: "plan", 107 | tasks: ["Task 1", "Task 2", "Task 3"] 108 | } 109 | 110 | // Execution phase 111 | { 112 | action: "execute", 113 | getNext: true 114 | } 115 | 116 | // Complete task 117 | { 118 | action: "complete", 119 | taskId: "task-123" 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.5.3/schema.json", 3 | "organizeImports": { 4 | "enabled": true 5 | }, 6 | "linter": { 7 | "enabled": true, 8 | "rules": { 9 | "recommended": true 10 | } 11 | }, 12 | "formatter": { 13 | "enabled": true, 14 | "indentStyle": "space", 15 | "indentWidth": 2, 16 | "lineWidth": 80 17 | }, 18 | "javascript": { 19 | "formatter": { 20 | "quoteStyle": "double", 21 | "trailingComma": "es5", 22 | "semicolons": "always" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 5 | import { 6 | CallToolRequestSchema, 7 | ListToolsRequestSchema, 8 | Tool, 9 | ToolSchema, 10 | } from "@modelcontextprotocol/sdk/types.js"; 11 | import * as fs from "node:fs/promises"; 12 | import * as path from "node:path"; 13 | import * as os from "node:os"; 14 | import { z } from "zod"; 15 | 16 | const DEFAULT_PATH = path.join(os.homedir(), "Documents", "tasks.json"); 17 | const TASK_FILE_PATH = process.env.TASK_MANAGER_FILE_PATH || DEFAULT_PATH; 18 | 19 | interface Task { 20 | id: string; 21 | title: string; 22 | description: string; 23 | done: boolean; 24 | approved: boolean; 25 | completedDetails: string; 26 | } 27 | 28 | interface RequestEntry { 29 | requestId: string; 30 | originalRequest: string; 31 | splitDetails: string; 32 | tasks: Task[]; 33 | completed: boolean; // marked true after all tasks done and request completion approved 34 | } 35 | 36 | interface TaskManagerFile { 37 | requests: RequestEntry[]; 38 | } 39 | 40 | // Zod Schemas 41 | const RequestPlanningSchema = z.object({ 42 | originalRequest: z.string(), 43 | splitDetails: z.string().optional(), 44 | tasks: z.array( 45 | z.object({ 46 | title: z.string(), 47 | description: z.string(), 48 | }) 49 | ), 50 | }); 51 | 52 | const GetNextTaskSchema = z.object({ 53 | requestId: z.string(), 54 | }); 55 | 56 | const MarkTaskDoneSchema = z.object({ 57 | requestId: z.string(), 58 | taskId: z.string(), 59 | completedDetails: z.string().optional(), 60 | }); 61 | 62 | const ApproveTaskCompletionSchema = z.object({ 63 | requestId: z.string(), 64 | taskId: z.string(), 65 | }); 66 | 67 | const ApproveRequestCompletionSchema = z.object({ 68 | requestId: z.string(), 69 | }); 70 | 71 | const OpenTaskDetailsSchema = z.object({ 72 | taskId: z.string(), 73 | }); 74 | 75 | const ListRequestsSchema = z.object({}); 76 | 77 | const AddTasksToRequestSchema = z.object({ 78 | requestId: z.string(), 79 | tasks: z.array( 80 | z.object({ 81 | title: z.string(), 82 | description: z.string(), 83 | }) 84 | ), 85 | }); 86 | 87 | const UpdateTaskSchema = z.object({ 88 | requestId: z.string(), 89 | taskId: z.string(), 90 | title: z.string().optional(), 91 | description: z.string().optional(), 92 | }); 93 | 94 | const DeleteTaskSchema = z.object({ 95 | requestId: z.string(), 96 | taskId: z.string(), 97 | }); 98 | 99 | // Tools with enriched English descriptions 100 | 101 | const REQUEST_PLANNING_TOOL: Tool = { 102 | name: "request_planning", 103 | description: 104 | "Register a new user request and plan its associated tasks. You must provide 'originalRequest' and 'tasks', and optionally 'splitDetails'.\n\n" + 105 | "This tool initiates a new workflow for handling a user's request. The workflow is as follows:\n" + 106 | "1. Use 'request_planning' to register a request and its tasks.\n" + 107 | "2. After adding tasks, you MUST use 'get_next_task' to retrieve the first task. A progress table will be displayed.\n" + 108 | "3. Use 'get_next_task' to retrieve the next uncompleted task.\n" + 109 | "4. **IMPORTANT:** After marking a task as done, the assistant MUST NOT proceed to another task without the user's approval. The user must explicitly approve the completed task using 'approve_task_completion'. A progress table will be displayed before each approval request.\n" + 110 | "5. Once a task is approved, you can proceed to 'get_next_task' again to fetch the next pending task.\n" + 111 | "6. Repeat this cycle until all tasks are done.\n" + 112 | "7. After all tasks are completed (and approved), 'get_next_task' will indicate that all tasks are done and that the request awaits approval for full completion.\n" + 113 | "8. The user must then approve the entire request's completion using 'approve_request_completion'. If the user does not approve and wants more tasks, you can again use 'request_planning' to add new tasks and continue the cycle.\n\n" + 114 | "The critical point is to always wait for user approval after completing each task and after all tasks are done, wait for request completion approval. Do not proceed automatically.", 115 | inputSchema: { 116 | type: "object", 117 | properties: { 118 | originalRequest: { type: "string" }, 119 | splitDetails: { type: "string" }, 120 | tasks: { 121 | type: "array", 122 | items: { 123 | type: "object", 124 | properties: { 125 | title: { type: "string" }, 126 | description: { type: "string" }, 127 | }, 128 | required: ["title", "description"], 129 | }, 130 | }, 131 | }, 132 | required: ["originalRequest", "tasks"], 133 | }, 134 | }; 135 | 136 | const GET_NEXT_TASK_TOOL: Tool = { 137 | name: "get_next_task", 138 | description: 139 | "Given a 'requestId', return the next pending task (not done yet). If all tasks are completed, it will indicate that no more tasks are left and that you must wait for the request completion approval.\n\n" + 140 | "A progress table showing the current status of all tasks will be displayed with each response.\n\n" + 141 | "If the same task is returned again or if no new task is provided after a task was marked as done but not yet approved, you MUST NOT proceed. In such a scenario, you must prompt the user for approval via 'approve_task_completion' before calling 'get_next_task' again. Do not skip the user's approval step.\n" + 142 | "In other words:\n" + 143 | "- After calling 'mark_task_done', do not call 'get_next_task' again until 'approve_task_completion' is called by the user.\n" + 144 | "- If 'get_next_task' returns 'all_tasks_done', it means all tasks have been completed. At this point, you must not start a new request or do anything else until the user decides to 'approve_request_completion' or possibly add more tasks via 'request_planning'.", 145 | inputSchema: { 146 | type: "object", 147 | properties: { 148 | requestId: { type: "string" }, 149 | }, 150 | required: ["requestId"], 151 | }, 152 | }; 153 | 154 | const MARK_TASK_DONE_TOOL: Tool = { 155 | name: "mark_task_done", 156 | description: 157 | "Mark a given task as done after you've completed it. Provide 'requestId' and 'taskId', and optionally 'completedDetails'.\n\n" + 158 | "After marking a task as done, a progress table will be displayed showing the updated status of all tasks.\n\n" + 159 | "After this, DO NOT proceed to 'get_next_task' again until the user has explicitly approved this completed task using 'approve_task_completion'.", 160 | inputSchema: { 161 | type: "object", 162 | properties: { 163 | requestId: { type: "string" }, 164 | taskId: { type: "string" }, 165 | completedDetails: { type: "string" }, 166 | }, 167 | required: ["requestId", "taskId"], 168 | }, 169 | }; 170 | 171 | const APPROVE_TASK_COMPLETION_TOOL: Tool = { 172 | name: "approve_task_completion", 173 | description: 174 | "Once the assistant has marked a task as done using 'mark_task_done', the user must call this tool to approve that the task is genuinely completed. Only after this approval can you proceed to 'get_next_task' to move on.\n\n" + 175 | "A progress table will be displayed before requesting approval, showing the current status of all tasks.\n\n" + 176 | "If the user does not approve, do not call 'get_next_task'. Instead, the user may request changes, or even re-plan tasks by using 'request_planning' again.", 177 | inputSchema: { 178 | type: "object", 179 | properties: { 180 | requestId: { type: "string" }, 181 | taskId: { type: "string" }, 182 | }, 183 | required: ["requestId", "taskId"], 184 | }, 185 | }; 186 | 187 | const APPROVE_REQUEST_COMPLETION_TOOL: Tool = { 188 | name: "approve_request_completion", 189 | description: 190 | "After all tasks are done and approved, this tool finalizes the entire request. The user must call this to confirm that the request is fully completed.\n\n" + 191 | "A progress table showing the final status of all tasks will be displayed before requesting final approval.\n\n" + 192 | "If not approved, the user can add new tasks using 'request_planning' and continue the process.", 193 | inputSchema: { 194 | type: "object", 195 | properties: { 196 | requestId: { type: "string" }, 197 | }, 198 | required: ["requestId"], 199 | }, 200 | }; 201 | 202 | const OPEN_TASK_DETAILS_TOOL: Tool = { 203 | name: "open_task_details", 204 | description: 205 | "Get details of a specific task by 'taskId'. This is for inspecting task information at any point.", 206 | inputSchema: { 207 | type: "object", 208 | properties: { 209 | taskId: { type: "string" }, 210 | }, 211 | required: ["taskId"], 212 | }, 213 | }; 214 | 215 | const LIST_REQUESTS_TOOL: Tool = { 216 | name: "list_requests", 217 | description: 218 | "List all requests with their basic information and summary of tasks. This provides a quick overview of all requests in the system.", 219 | inputSchema: { 220 | type: "object", 221 | properties: {}, 222 | }, 223 | }; 224 | 225 | const ADD_TASKS_TO_REQUEST_TOOL: Tool = { 226 | name: "add_tasks_to_request", 227 | description: 228 | "Add new tasks to an existing request. This allows extending a request with additional tasks.\n\n" + 229 | "A progress table will be displayed showing all tasks including the newly added ones.", 230 | inputSchema: { 231 | type: "object", 232 | properties: { 233 | requestId: { type: "string" }, 234 | tasks: { 235 | type: "array", 236 | items: { 237 | type: "object", 238 | properties: { 239 | title: { type: "string" }, 240 | description: { type: "string" }, 241 | }, 242 | required: ["title", "description"], 243 | }, 244 | }, 245 | }, 246 | required: ["requestId", "tasks"], 247 | }, 248 | }; 249 | 250 | const UPDATE_TASK_TOOL: Tool = { 251 | name: "update_task", 252 | description: 253 | "Update an existing task's title and/or description. Only uncompleted tasks can be updated.\n\n" + 254 | "A progress table will be displayed showing the updated task information.", 255 | inputSchema: { 256 | type: "object", 257 | properties: { 258 | requestId: { type: "string" }, 259 | taskId: { type: "string" }, 260 | title: { type: "string" }, 261 | description: { type: "string" }, 262 | }, 263 | required: ["requestId", "taskId"], 264 | }, 265 | }; 266 | 267 | const DELETE_TASK_TOOL: Tool = { 268 | name: "delete_task", 269 | description: 270 | "Delete a specific task from a request. Only uncompleted tasks can be deleted.\n\n" + 271 | "A progress table will be displayed showing the remaining tasks after deletion.", 272 | inputSchema: { 273 | type: "object", 274 | properties: { 275 | requestId: { type: "string" }, 276 | taskId: { type: "string" }, 277 | }, 278 | required: ["requestId", "taskId"], 279 | }, 280 | }; 281 | 282 | class TaskManagerServer { 283 | private requestCounter = 0; 284 | private taskCounter = 0; 285 | private data: TaskManagerFile = { requests: [] }; 286 | 287 | constructor() { 288 | this.loadTasks(); 289 | } 290 | 291 | private async loadTasks() { 292 | try { 293 | const data = await fs.readFile(TASK_FILE_PATH, "utf-8"); 294 | this.data = JSON.parse(data); 295 | const allTaskIds: number[] = []; 296 | const allRequestIds: number[] = []; 297 | 298 | for (const req of this.data.requests) { 299 | const reqNum = Number.parseInt(req.requestId.replace("req-", ""), 10); 300 | if (!Number.isNaN(reqNum)) { 301 | allRequestIds.push(reqNum); 302 | } 303 | for (const t of req.tasks) { 304 | const tNum = Number.parseInt(t.id.replace("task-", ""), 10); 305 | if (!Number.isNaN(tNum)) { 306 | allTaskIds.push(tNum); 307 | } 308 | } 309 | } 310 | 311 | this.requestCounter = 312 | allRequestIds.length > 0 ? Math.max(...allRequestIds) : 0; 313 | this.taskCounter = allTaskIds.length > 0 ? Math.max(...allTaskIds) : 0; 314 | } catch (error) { 315 | this.data = { requests: [] }; 316 | } 317 | } 318 | 319 | private async saveTasks() { 320 | try { 321 | await fs.writeFile( 322 | TASK_FILE_PATH, 323 | JSON.stringify(this.data, null, 2), 324 | "utf-8" 325 | ); 326 | } catch (error) { 327 | if (error instanceof Error && error.message.includes("EROFS")) { 328 | console.error("EROFS: read-only file system. Cannot save tasks."); 329 | throw error; 330 | } 331 | throw error; 332 | } 333 | } 334 | 335 | private formatTaskProgressTable(requestId: string): string { 336 | const req = this.data.requests.find((r) => r.requestId === requestId); 337 | if (!req) return "Request not found"; 338 | 339 | let table = "\nProgress Status:\n"; 340 | table += "| Task ID | Title | Description | Status | Approval |\n"; 341 | table += "|----------|----------|------|------|----------|\n"; 342 | 343 | for (const task of req.tasks) { 344 | const status = task.done ? "✅ Done" : "🔄 In Progress"; 345 | const approved = task.approved ? "✅ Approved" : "⏳ Pending"; 346 | table += `| ${task.id} | ${task.title} | ${task.description} | ${status} | ${approved} |\n`; 347 | } 348 | 349 | return table; 350 | } 351 | 352 | private formatRequestsList(): string { 353 | let output = "\nRequests List:\n"; 354 | output += 355 | "| Request ID | Original Request | Total Tasks | Completed | Approved |\n"; 356 | output += 357 | "|------------|------------------|-------------|-----------|----------|\n"; 358 | 359 | for (const req of this.data.requests) { 360 | const totalTasks = req.tasks.length; 361 | const completedTasks = req.tasks.filter((t) => t.done).length; 362 | const approvedTasks = req.tasks.filter((t) => t.approved).length; 363 | output += `| ${req.requestId} | ${req.originalRequest.substring(0, 30)}${req.originalRequest.length > 30 ? "..." : ""} | ${totalTasks} | ${completedTasks} | ${approvedTasks} |\n`; 364 | } 365 | 366 | return output; 367 | } 368 | 369 | public async requestPlanning( 370 | originalRequest: string, 371 | tasks: { title: string; description: string }[], 372 | splitDetails?: string 373 | ) { 374 | await this.loadTasks(); 375 | this.requestCounter += 1; 376 | const requestId = `req-${this.requestCounter}`; 377 | 378 | const newTasks: Task[] = []; 379 | for (const taskDef of tasks) { 380 | this.taskCounter += 1; 381 | newTasks.push({ 382 | id: `task-${this.taskCounter}`, 383 | title: taskDef.title, 384 | description: taskDef.description, 385 | done: false, 386 | approved: false, 387 | completedDetails: "", 388 | }); 389 | } 390 | 391 | this.data.requests.push({ 392 | requestId, 393 | originalRequest, 394 | splitDetails: splitDetails || originalRequest, 395 | tasks: newTasks, 396 | completed: false, 397 | }); 398 | 399 | await this.saveTasks(); 400 | 401 | const progressTable = this.formatTaskProgressTable(requestId); 402 | 403 | return { 404 | status: "planned", 405 | requestId, 406 | totalTasks: newTasks.length, 407 | tasks: newTasks.map((t) => ({ 408 | id: t.id, 409 | title: t.title, 410 | description: t.description, 411 | })), 412 | message: `Tasks have been successfully added. Please use 'get_next_task' to retrieve the first task.\n${progressTable}`, 413 | }; 414 | } 415 | 416 | public async getNextTask(requestId: string) { 417 | await this.loadTasks(); 418 | const req = this.data.requests.find((r) => r.requestId === requestId); 419 | if (!req) { 420 | return { status: "error", message: "Request not found" }; 421 | } 422 | if (req.completed) { 423 | return { 424 | status: "already_completed", 425 | message: "Request already completed.", 426 | }; 427 | } 428 | const nextTask = req.tasks.find((t) => !t.done); 429 | if (!nextTask) { 430 | // all tasks done? 431 | const allDone = req.tasks.every((t) => t.done); 432 | if (allDone && !req.completed) { 433 | const progressTable = this.formatTaskProgressTable(requestId); 434 | return { 435 | status: "all_tasks_done", 436 | message: `All tasks have been completed. Awaiting request completion approval.\n${progressTable}`, 437 | }; 438 | } 439 | return { status: "no_next_task", message: "No undone tasks found." }; 440 | } 441 | 442 | const progressTable = this.formatTaskProgressTable(requestId); 443 | return { 444 | status: "next_task", 445 | task: { 446 | id: nextTask.id, 447 | title: nextTask.title, 448 | description: nextTask.description, 449 | }, 450 | message: `Next task is ready. Task approval will be required after completion.\n${progressTable}`, 451 | }; 452 | } 453 | 454 | public async markTaskDone( 455 | requestId: string, 456 | taskId: string, 457 | completedDetails?: string 458 | ) { 459 | await this.loadTasks(); 460 | const req = this.data.requests.find((r) => r.requestId === requestId); 461 | if (!req) return { status: "error", message: "Request not found" }; 462 | const task = req.tasks.find((t) => t.id === taskId); 463 | if (!task) return { status: "error", message: "Task not found" }; 464 | if (task.done) 465 | return { 466 | status: "already_done", 467 | message: "Task is already marked done.", 468 | }; 469 | 470 | task.done = true; 471 | task.completedDetails = completedDetails || ""; 472 | await this.saveTasks(); 473 | return { 474 | status: "task_marked_done", 475 | requestId: req.requestId, 476 | task: { 477 | id: task.id, 478 | title: task.title, 479 | description: task.description, 480 | completedDetails: task.completedDetails, 481 | approved: task.approved, 482 | }, 483 | }; 484 | } 485 | 486 | public async approveTaskCompletion(requestId: string, taskId: string) { 487 | await this.loadTasks(); 488 | const req = this.data.requests.find((r) => r.requestId === requestId); 489 | if (!req) return { status: "error", message: "Request not found" }; 490 | const task = req.tasks.find((t) => t.id === taskId); 491 | if (!task) return { status: "error", message: "Task not found" }; 492 | if (!task.done) return { status: "error", message: "Task not done yet." }; 493 | if (task.approved) 494 | return { status: "already_approved", message: "Task already approved." }; 495 | 496 | task.approved = true; 497 | await this.saveTasks(); 498 | return { 499 | status: "task_approved", 500 | requestId: req.requestId, 501 | task: { 502 | id: task.id, 503 | title: task.title, 504 | description: task.description, 505 | completedDetails: task.completedDetails, 506 | approved: task.approved, 507 | }, 508 | }; 509 | } 510 | 511 | public async approveRequestCompletion(requestId: string) { 512 | await this.loadTasks(); 513 | const req = this.data.requests.find((r) => r.requestId === requestId); 514 | if (!req) return { status: "error", message: "Request not found" }; 515 | 516 | // Check if all tasks are done and approved 517 | const allDone = req.tasks.every((t) => t.done); 518 | if (!allDone) { 519 | return { status: "error", message: "Not all tasks are done." }; 520 | } 521 | const allApproved = req.tasks.every((t) => t.done && t.approved); 522 | if (!allApproved) { 523 | return { status: "error", message: "Not all done tasks are approved." }; 524 | } 525 | 526 | req.completed = true; 527 | await this.saveTasks(); 528 | return { 529 | status: "request_approved_complete", 530 | requestId: req.requestId, 531 | message: "Request is fully completed and approved.", 532 | }; 533 | } 534 | 535 | public async openTaskDetails(taskId: string) { 536 | await this.loadTasks(); 537 | for (const req of this.data.requests) { 538 | const target = req.tasks.find((t) => t.id === taskId); 539 | if (target) { 540 | return { 541 | status: "task_details", 542 | requestId: req.requestId, 543 | originalRequest: req.originalRequest, 544 | splitDetails: req.splitDetails, 545 | completed: req.completed, 546 | task: { 547 | id: target.id, 548 | title: target.title, 549 | description: target.description, 550 | done: target.done, 551 | approved: target.approved, 552 | completedDetails: target.completedDetails, 553 | }, 554 | }; 555 | } 556 | } 557 | return { status: "task_not_found", message: "No such task found" }; 558 | } 559 | 560 | public async listRequests() { 561 | await this.loadTasks(); 562 | const requestsList = this.formatRequestsList(); 563 | return { 564 | status: "requests_listed", 565 | message: `Current requests in the system:\n${requestsList}`, 566 | requests: this.data.requests.map((req) => ({ 567 | requestId: req.requestId, 568 | originalRequest: req.originalRequest, 569 | totalTasks: req.tasks.length, 570 | completedTasks: req.tasks.filter((t) => t.done).length, 571 | approvedTasks: req.tasks.filter((t) => t.approved).length, 572 | })), 573 | }; 574 | } 575 | 576 | public async addTasksToRequest( 577 | requestId: string, 578 | tasks: { title: string; description: string }[] 579 | ) { 580 | await this.loadTasks(); 581 | const req = this.data.requests.find((r) => r.requestId === requestId); 582 | if (!req) return { status: "error", message: "Request not found" }; 583 | if (req.completed) 584 | return { 585 | status: "error", 586 | message: "Cannot add tasks to completed request", 587 | }; 588 | 589 | const newTasks: Task[] = []; 590 | for (const taskDef of tasks) { 591 | this.taskCounter += 1; 592 | newTasks.push({ 593 | id: `task-${this.taskCounter}`, 594 | title: taskDef.title, 595 | description: taskDef.description, 596 | done: false, 597 | approved: false, 598 | completedDetails: "", 599 | }); 600 | } 601 | 602 | req.tasks.push(...newTasks); 603 | await this.saveTasks(); 604 | 605 | const progressTable = this.formatTaskProgressTable(requestId); 606 | return { 607 | status: "tasks_added", 608 | message: `Added ${newTasks.length} new tasks to request.\n${progressTable}`, 609 | newTasks: newTasks.map((t) => ({ 610 | id: t.id, 611 | title: t.title, 612 | description: t.description, 613 | })), 614 | }; 615 | } 616 | 617 | public async updateTask( 618 | requestId: string, 619 | taskId: string, 620 | updates: { title?: string; description?: string } 621 | ) { 622 | await this.loadTasks(); 623 | const req = this.data.requests.find((r) => r.requestId === requestId); 624 | if (!req) return { status: "error", message: "Request not found" }; 625 | 626 | const task = req.tasks.find((t) => t.id === taskId); 627 | if (!task) return { status: "error", message: "Task not found" }; 628 | if (task.done) 629 | return { status: "error", message: "Cannot update completed task" }; 630 | 631 | if (updates.title) task.title = updates.title; 632 | if (updates.description) task.description = updates.description; 633 | 634 | await this.saveTasks(); 635 | 636 | const progressTable = this.formatTaskProgressTable(requestId); 637 | return { 638 | status: "task_updated", 639 | message: `Task ${taskId} has been updated.\n${progressTable}`, 640 | task: { 641 | id: task.id, 642 | title: task.title, 643 | description: task.description, 644 | }, 645 | }; 646 | } 647 | 648 | public async deleteTask(requestId: string, taskId: string) { 649 | await this.loadTasks(); 650 | const req = this.data.requests.find((r) => r.requestId === requestId); 651 | if (!req) return { status: "error", message: "Request not found" }; 652 | 653 | const taskIndex = req.tasks.findIndex((t) => t.id === taskId); 654 | if (taskIndex === -1) return { status: "error", message: "Task not found" }; 655 | if (req.tasks[taskIndex].done) 656 | return { status: "error", message: "Cannot delete completed task" }; 657 | 658 | req.tasks.splice(taskIndex, 1); 659 | await this.saveTasks(); 660 | 661 | const progressTable = this.formatTaskProgressTable(requestId); 662 | return { 663 | status: "task_deleted", 664 | message: `Task ${taskId} has been deleted.\n${progressTable}`, 665 | }; 666 | } 667 | } 668 | 669 | const server = new Server( 670 | { 671 | name: "task-manager-server", 672 | version: "2.0.0", 673 | }, 674 | { 675 | capabilities: { 676 | tools: {}, 677 | }, 678 | } 679 | ); 680 | 681 | const taskManagerServer = new TaskManagerServer(); 682 | 683 | server.setRequestHandler(ListToolsRequestSchema, async () => ({ 684 | tools: [ 685 | REQUEST_PLANNING_TOOL, 686 | GET_NEXT_TASK_TOOL, 687 | MARK_TASK_DONE_TOOL, 688 | APPROVE_TASK_COMPLETION_TOOL, 689 | APPROVE_REQUEST_COMPLETION_TOOL, 690 | OPEN_TASK_DETAILS_TOOL, 691 | LIST_REQUESTS_TOOL, 692 | ADD_TASKS_TO_REQUEST_TOOL, 693 | UPDATE_TASK_TOOL, 694 | DELETE_TASK_TOOL, 695 | ], 696 | })); 697 | 698 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 699 | try { 700 | const { name, arguments: args } = request.params; 701 | 702 | switch (name) { 703 | case "request_planning": { 704 | const parsed = RequestPlanningSchema.safeParse(args); 705 | if (!parsed.success) { 706 | throw new Error(`Invalid arguments: ${parsed.error}`); 707 | } 708 | const { originalRequest, tasks, splitDetails } = parsed.data; 709 | const result = await taskManagerServer.requestPlanning( 710 | originalRequest, 711 | tasks, 712 | splitDetails 713 | ); 714 | return { 715 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 716 | }; 717 | } 718 | 719 | case "get_next_task": { 720 | const parsed = GetNextTaskSchema.safeParse(args); 721 | if (!parsed.success) { 722 | throw new Error(`Invalid arguments: ${parsed.error}`); 723 | } 724 | const result = await taskManagerServer.getNextTask( 725 | parsed.data.requestId 726 | ); 727 | return { 728 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 729 | }; 730 | } 731 | 732 | case "mark_task_done": { 733 | const parsed = MarkTaskDoneSchema.safeParse(args); 734 | if (!parsed.success) { 735 | throw new Error(`Invalid arguments: ${parsed.error}`); 736 | } 737 | const { requestId, taskId, completedDetails } = parsed.data; 738 | const result = await taskManagerServer.markTaskDone( 739 | requestId, 740 | taskId, 741 | completedDetails 742 | ); 743 | return { 744 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 745 | }; 746 | } 747 | 748 | case "approve_task_completion": { 749 | const parsed = ApproveTaskCompletionSchema.safeParse(args); 750 | if (!parsed.success) { 751 | throw new Error(`Invalid arguments: ${parsed.error}`); 752 | } 753 | const { requestId, taskId } = parsed.data; 754 | const result = await taskManagerServer.approveTaskCompletion( 755 | requestId, 756 | taskId 757 | ); 758 | return { 759 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 760 | }; 761 | } 762 | 763 | case "approve_request_completion": { 764 | const parsed = ApproveRequestCompletionSchema.safeParse(args); 765 | if (!parsed.success) { 766 | throw new Error(`Invalid arguments: ${parsed.error}`); 767 | } 768 | const { requestId } = parsed.data; 769 | const result = 770 | await taskManagerServer.approveRequestCompletion(requestId); 771 | return { 772 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 773 | }; 774 | } 775 | 776 | case "open_task_details": { 777 | const parsed = OpenTaskDetailsSchema.safeParse(args); 778 | if (!parsed.success) { 779 | throw new Error(`Invalid arguments: ${parsed.error}`); 780 | } 781 | const { taskId } = parsed.data; 782 | const result = await taskManagerServer.openTaskDetails(taskId); 783 | return { 784 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 785 | }; 786 | } 787 | 788 | case "list_requests": { 789 | const parsed = ListRequestsSchema.safeParse(args); 790 | if (!parsed.success) { 791 | throw new Error(`Invalid arguments: ${parsed.error}`); 792 | } 793 | const result = await taskManagerServer.listRequests(); 794 | return { 795 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 796 | }; 797 | } 798 | 799 | case "add_tasks_to_request": { 800 | const parsed = AddTasksToRequestSchema.safeParse(args); 801 | if (!parsed.success) { 802 | throw new Error(`Invalid arguments: ${parsed.error}`); 803 | } 804 | const { requestId, tasks } = parsed.data; 805 | const result = await taskManagerServer.addTasksToRequest( 806 | requestId, 807 | tasks 808 | ); 809 | return { 810 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 811 | }; 812 | } 813 | 814 | case "update_task": { 815 | const parsed = UpdateTaskSchema.safeParse(args); 816 | if (!parsed.success) { 817 | throw new Error(`Invalid arguments: ${parsed.error}`); 818 | } 819 | const { requestId, taskId, title, description } = parsed.data; 820 | const result = await taskManagerServer.updateTask(requestId, taskId, { 821 | title, 822 | description, 823 | }); 824 | return { 825 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 826 | }; 827 | } 828 | 829 | case "delete_task": { 830 | const parsed = DeleteTaskSchema.safeParse(args); 831 | if (!parsed.success) { 832 | throw new Error(`Invalid arguments: ${parsed.error}`); 833 | } 834 | const { requestId, taskId } = parsed.data; 835 | const result = await taskManagerServer.deleteTask(requestId, taskId); 836 | return { 837 | content: [{ type: "text", text: JSON.stringify(result, null, 2) }], 838 | }; 839 | } 840 | 841 | default: 842 | throw new Error(`Unknown tool: ${name}`); 843 | } 844 | } catch (error) { 845 | const errorMessage = error instanceof Error ? error.message : String(error); 846 | return { 847 | content: [{ type: "text", text: `Error: ${errorMessage}` }], 848 | isError: true, 849 | }; 850 | } 851 | }); 852 | 853 | async function runServer() { 854 | const transport = new StdioServerTransport(); 855 | await server.connect(transport); 856 | console.error( 857 | `Task Manager MCP Server running. Saving tasks at: ${TASK_FILE_PATH}` 858 | ); 859 | } 860 | 861 | runServer().catch((error) => { 862 | console.error("Fatal error running server:", error); 863 | process.exit(1); 864 | }); 865 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kazuph/mcp-taskmanager", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@kazuph/mcp-taskmanager", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@modelcontextprotocol/sdk": "0.5.0", 13 | "chalk": "^5.3.0", 14 | "glob": "^10.3.10", 15 | "zod": "^3.23.8", 16 | "zod-to-json-schema": "^3.23.5" 17 | }, 18 | "bin": { 19 | "mcp-taskmanager": "dist/index.js" 20 | }, 21 | "devDependencies": { 22 | "@types/json-schema": "^7.0.15", 23 | "@types/node": "^20.11.0", 24 | "shx": "^0.3.4", 25 | "typescript": "^5.3.3" 26 | } 27 | }, 28 | "node_modules/@isaacs/cliui": { 29 | "version": "8.0.2", 30 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 31 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 32 | "license": "ISC", 33 | "dependencies": { 34 | "string-width": "^5.1.2", 35 | "string-width-cjs": "npm:string-width@^4.2.0", 36 | "strip-ansi": "^7.0.1", 37 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 38 | "wrap-ansi": "^8.1.0", 39 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 40 | }, 41 | "engines": { 42 | "node": ">=12" 43 | } 44 | }, 45 | "node_modules/@modelcontextprotocol/sdk": { 46 | "version": "0.5.0", 47 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.5.0.tgz", 48 | "integrity": "sha512-RXgulUX6ewvxjAG0kOpLMEdXXWkzWgaoCGaA2CwNW7cQCIphjpJhjpHSiaPdVCnisjRF/0Cm9KWHUuIoeiAblQ==", 49 | "license": "MIT", 50 | "dependencies": { 51 | "content-type": "^1.0.5", 52 | "raw-body": "^3.0.0", 53 | "zod": "^3.23.8" 54 | } 55 | }, 56 | "node_modules/@pkgjs/parseargs": { 57 | "version": "0.11.0", 58 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 59 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 60 | "license": "MIT", 61 | "optional": true, 62 | "engines": { 63 | "node": ">=14" 64 | } 65 | }, 66 | "node_modules/@types/json-schema": { 67 | "version": "7.0.15", 68 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 69 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 70 | "dev": true, 71 | "license": "MIT" 72 | }, 73 | "node_modules/@types/node": { 74 | "version": "20.17.10", 75 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", 76 | "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", 77 | "dev": true, 78 | "license": "MIT", 79 | "dependencies": { 80 | "undici-types": "~6.19.2" 81 | } 82 | }, 83 | "node_modules/ansi-regex": { 84 | "version": "6.1.0", 85 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 86 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 87 | "license": "MIT", 88 | "engines": { 89 | "node": ">=12" 90 | }, 91 | "funding": { 92 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 93 | } 94 | }, 95 | "node_modules/ansi-styles": { 96 | "version": "6.2.1", 97 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 98 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 99 | "license": "MIT", 100 | "engines": { 101 | "node": ">=12" 102 | }, 103 | "funding": { 104 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 105 | } 106 | }, 107 | "node_modules/balanced-match": { 108 | "version": "1.0.2", 109 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 110 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 111 | "license": "MIT" 112 | }, 113 | "node_modules/brace-expansion": { 114 | "version": "2.0.1", 115 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 116 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 117 | "license": "MIT", 118 | "dependencies": { 119 | "balanced-match": "^1.0.0" 120 | } 121 | }, 122 | "node_modules/bytes": { 123 | "version": "3.1.2", 124 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 125 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 126 | "license": "MIT", 127 | "engines": { 128 | "node": ">= 0.8" 129 | } 130 | }, 131 | "node_modules/chalk": { 132 | "version": "5.3.0", 133 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", 134 | "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", 135 | "license": "MIT", 136 | "engines": { 137 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 138 | }, 139 | "funding": { 140 | "url": "https://github.com/chalk/chalk?sponsor=1" 141 | } 142 | }, 143 | "node_modules/color-convert": { 144 | "version": "2.0.1", 145 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 146 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 147 | "license": "MIT", 148 | "dependencies": { 149 | "color-name": "~1.1.4" 150 | }, 151 | "engines": { 152 | "node": ">=7.0.0" 153 | } 154 | }, 155 | "node_modules/color-name": { 156 | "version": "1.1.4", 157 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 158 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 159 | "license": "MIT" 160 | }, 161 | "node_modules/concat-map": { 162 | "version": "0.0.1", 163 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 164 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 165 | "dev": true, 166 | "license": "MIT" 167 | }, 168 | "node_modules/content-type": { 169 | "version": "1.0.5", 170 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 171 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 172 | "license": "MIT", 173 | "engines": { 174 | "node": ">= 0.6" 175 | } 176 | }, 177 | "node_modules/cross-spawn": { 178 | "version": "7.0.6", 179 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 180 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 181 | "license": "MIT", 182 | "dependencies": { 183 | "path-key": "^3.1.0", 184 | "shebang-command": "^2.0.0", 185 | "which": "^2.0.1" 186 | }, 187 | "engines": { 188 | "node": ">= 8" 189 | } 190 | }, 191 | "node_modules/depd": { 192 | "version": "2.0.0", 193 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 194 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 195 | "license": "MIT", 196 | "engines": { 197 | "node": ">= 0.8" 198 | } 199 | }, 200 | "node_modules/eastasianwidth": { 201 | "version": "0.2.0", 202 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 203 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 204 | "license": "MIT" 205 | }, 206 | "node_modules/emoji-regex": { 207 | "version": "9.2.2", 208 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 209 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 210 | "license": "MIT" 211 | }, 212 | "node_modules/foreground-child": { 213 | "version": "3.3.0", 214 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", 215 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", 216 | "license": "ISC", 217 | "dependencies": { 218 | "cross-spawn": "^7.0.0", 219 | "signal-exit": "^4.0.1" 220 | }, 221 | "engines": { 222 | "node": ">=14" 223 | }, 224 | "funding": { 225 | "url": "https://github.com/sponsors/isaacs" 226 | } 227 | }, 228 | "node_modules/fs.realpath": { 229 | "version": "1.0.0", 230 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 231 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 232 | "dev": true, 233 | "license": "ISC" 234 | }, 235 | "node_modules/function-bind": { 236 | "version": "1.1.2", 237 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 238 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 239 | "dev": true, 240 | "license": "MIT", 241 | "funding": { 242 | "url": "https://github.com/sponsors/ljharb" 243 | } 244 | }, 245 | "node_modules/glob": { 246 | "version": "10.4.5", 247 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 248 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 249 | "license": "ISC", 250 | "dependencies": { 251 | "foreground-child": "^3.1.0", 252 | "jackspeak": "^3.1.2", 253 | "minimatch": "^9.0.4", 254 | "minipass": "^7.1.2", 255 | "package-json-from-dist": "^1.0.0", 256 | "path-scurry": "^1.11.1" 257 | }, 258 | "bin": { 259 | "glob": "dist/esm/bin.mjs" 260 | }, 261 | "funding": { 262 | "url": "https://github.com/sponsors/isaacs" 263 | } 264 | }, 265 | "node_modules/hasown": { 266 | "version": "2.0.2", 267 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 268 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 269 | "dev": true, 270 | "license": "MIT", 271 | "dependencies": { 272 | "function-bind": "^1.1.2" 273 | }, 274 | "engines": { 275 | "node": ">= 0.4" 276 | } 277 | }, 278 | "node_modules/http-errors": { 279 | "version": "2.0.0", 280 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 281 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 282 | "license": "MIT", 283 | "dependencies": { 284 | "depd": "2.0.0", 285 | "inherits": "2.0.4", 286 | "setprototypeof": "1.2.0", 287 | "statuses": "2.0.1", 288 | "toidentifier": "1.0.1" 289 | }, 290 | "engines": { 291 | "node": ">= 0.8" 292 | } 293 | }, 294 | "node_modules/iconv-lite": { 295 | "version": "0.6.3", 296 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 297 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 298 | "license": "MIT", 299 | "dependencies": { 300 | "safer-buffer": ">= 2.1.2 < 3.0.0" 301 | }, 302 | "engines": { 303 | "node": ">=0.10.0" 304 | } 305 | }, 306 | "node_modules/inflight": { 307 | "version": "1.0.6", 308 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 309 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 310 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 311 | "dev": true, 312 | "license": "ISC", 313 | "dependencies": { 314 | "once": "^1.3.0", 315 | "wrappy": "1" 316 | } 317 | }, 318 | "node_modules/inherits": { 319 | "version": "2.0.4", 320 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 321 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 322 | "license": "ISC" 323 | }, 324 | "node_modules/interpret": { 325 | "version": "1.4.0", 326 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", 327 | "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", 328 | "dev": true, 329 | "license": "MIT", 330 | "engines": { 331 | "node": ">= 0.10" 332 | } 333 | }, 334 | "node_modules/is-core-module": { 335 | "version": "2.15.1", 336 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", 337 | "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", 338 | "dev": true, 339 | "license": "MIT", 340 | "dependencies": { 341 | "hasown": "^2.0.2" 342 | }, 343 | "engines": { 344 | "node": ">= 0.4" 345 | }, 346 | "funding": { 347 | "url": "https://github.com/sponsors/ljharb" 348 | } 349 | }, 350 | "node_modules/is-fullwidth-code-point": { 351 | "version": "3.0.0", 352 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 353 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 354 | "license": "MIT", 355 | "engines": { 356 | "node": ">=8" 357 | } 358 | }, 359 | "node_modules/isexe": { 360 | "version": "2.0.0", 361 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 362 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 363 | "license": "ISC" 364 | }, 365 | "node_modules/jackspeak": { 366 | "version": "3.4.3", 367 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 368 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 369 | "license": "BlueOak-1.0.0", 370 | "dependencies": { 371 | "@isaacs/cliui": "^8.0.2" 372 | }, 373 | "funding": { 374 | "url": "https://github.com/sponsors/isaacs" 375 | }, 376 | "optionalDependencies": { 377 | "@pkgjs/parseargs": "^0.11.0" 378 | } 379 | }, 380 | "node_modules/lru-cache": { 381 | "version": "10.4.3", 382 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 383 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 384 | "license": "ISC" 385 | }, 386 | "node_modules/minimatch": { 387 | "version": "9.0.5", 388 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 389 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 390 | "license": "ISC", 391 | "dependencies": { 392 | "brace-expansion": "^2.0.1" 393 | }, 394 | "engines": { 395 | "node": ">=16 || 14 >=14.17" 396 | }, 397 | "funding": { 398 | "url": "https://github.com/sponsors/isaacs" 399 | } 400 | }, 401 | "node_modules/minimist": { 402 | "version": "1.2.8", 403 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 404 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 405 | "dev": true, 406 | "license": "MIT", 407 | "funding": { 408 | "url": "https://github.com/sponsors/ljharb" 409 | } 410 | }, 411 | "node_modules/minipass": { 412 | "version": "7.1.2", 413 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 414 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 415 | "license": "ISC", 416 | "engines": { 417 | "node": ">=16 || 14 >=14.17" 418 | } 419 | }, 420 | "node_modules/once": { 421 | "version": "1.4.0", 422 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 423 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 424 | "dev": true, 425 | "license": "ISC", 426 | "dependencies": { 427 | "wrappy": "1" 428 | } 429 | }, 430 | "node_modules/package-json-from-dist": { 431 | "version": "1.0.1", 432 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 433 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 434 | "license": "BlueOak-1.0.0" 435 | }, 436 | "node_modules/path-is-absolute": { 437 | "version": "1.0.1", 438 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 439 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 440 | "dev": true, 441 | "license": "MIT", 442 | "engines": { 443 | "node": ">=0.10.0" 444 | } 445 | }, 446 | "node_modules/path-key": { 447 | "version": "3.1.1", 448 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 449 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 450 | "license": "MIT", 451 | "engines": { 452 | "node": ">=8" 453 | } 454 | }, 455 | "node_modules/path-parse": { 456 | "version": "1.0.7", 457 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 458 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 459 | "dev": true, 460 | "license": "MIT" 461 | }, 462 | "node_modules/path-scurry": { 463 | "version": "1.11.1", 464 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 465 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 466 | "license": "BlueOak-1.0.0", 467 | "dependencies": { 468 | "lru-cache": "^10.2.0", 469 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 470 | }, 471 | "engines": { 472 | "node": ">=16 || 14 >=14.18" 473 | }, 474 | "funding": { 475 | "url": "https://github.com/sponsors/isaacs" 476 | } 477 | }, 478 | "node_modules/raw-body": { 479 | "version": "3.0.0", 480 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 481 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 482 | "license": "MIT", 483 | "dependencies": { 484 | "bytes": "3.1.2", 485 | "http-errors": "2.0.0", 486 | "iconv-lite": "0.6.3", 487 | "unpipe": "1.0.0" 488 | }, 489 | "engines": { 490 | "node": ">= 0.8" 491 | } 492 | }, 493 | "node_modules/rechoir": { 494 | "version": "0.6.2", 495 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 496 | "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", 497 | "dev": true, 498 | "dependencies": { 499 | "resolve": "^1.1.6" 500 | }, 501 | "engines": { 502 | "node": ">= 0.10" 503 | } 504 | }, 505 | "node_modules/resolve": { 506 | "version": "1.22.8", 507 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 508 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 509 | "dev": true, 510 | "license": "MIT", 511 | "dependencies": { 512 | "is-core-module": "^2.13.0", 513 | "path-parse": "^1.0.7", 514 | "supports-preserve-symlinks-flag": "^1.0.0" 515 | }, 516 | "bin": { 517 | "resolve": "bin/resolve" 518 | }, 519 | "funding": { 520 | "url": "https://github.com/sponsors/ljharb" 521 | } 522 | }, 523 | "node_modules/safer-buffer": { 524 | "version": "2.1.2", 525 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 526 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 527 | "license": "MIT" 528 | }, 529 | "node_modules/setprototypeof": { 530 | "version": "1.2.0", 531 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 532 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 533 | "license": "ISC" 534 | }, 535 | "node_modules/shebang-command": { 536 | "version": "2.0.0", 537 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 538 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 539 | "license": "MIT", 540 | "dependencies": { 541 | "shebang-regex": "^3.0.0" 542 | }, 543 | "engines": { 544 | "node": ">=8" 545 | } 546 | }, 547 | "node_modules/shebang-regex": { 548 | "version": "3.0.0", 549 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 550 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 551 | "license": "MIT", 552 | "engines": { 553 | "node": ">=8" 554 | } 555 | }, 556 | "node_modules/shelljs": { 557 | "version": "0.8.5", 558 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", 559 | "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", 560 | "dev": true, 561 | "license": "BSD-3-Clause", 562 | "dependencies": { 563 | "glob": "^7.0.0", 564 | "interpret": "^1.0.0", 565 | "rechoir": "^0.6.2" 566 | }, 567 | "bin": { 568 | "shjs": "bin/shjs" 569 | }, 570 | "engines": { 571 | "node": ">=4" 572 | } 573 | }, 574 | "node_modules/shelljs/node_modules/brace-expansion": { 575 | "version": "1.1.11", 576 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 577 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 578 | "dev": true, 579 | "license": "MIT", 580 | "dependencies": { 581 | "balanced-match": "^1.0.0", 582 | "concat-map": "0.0.1" 583 | } 584 | }, 585 | "node_modules/shelljs/node_modules/glob": { 586 | "version": "7.2.3", 587 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 588 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 589 | "deprecated": "Glob versions prior to v9 are no longer supported", 590 | "dev": true, 591 | "license": "ISC", 592 | "dependencies": { 593 | "fs.realpath": "^1.0.0", 594 | "inflight": "^1.0.4", 595 | "inherits": "2", 596 | "minimatch": "^3.1.1", 597 | "once": "^1.3.0", 598 | "path-is-absolute": "^1.0.0" 599 | }, 600 | "engines": { 601 | "node": "*" 602 | }, 603 | "funding": { 604 | "url": "https://github.com/sponsors/isaacs" 605 | } 606 | }, 607 | "node_modules/shelljs/node_modules/minimatch": { 608 | "version": "3.1.2", 609 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 610 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 611 | "dev": true, 612 | "license": "ISC", 613 | "dependencies": { 614 | "brace-expansion": "^1.1.7" 615 | }, 616 | "engines": { 617 | "node": "*" 618 | } 619 | }, 620 | "node_modules/shx": { 621 | "version": "0.3.4", 622 | "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", 623 | "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", 624 | "dev": true, 625 | "license": "MIT", 626 | "dependencies": { 627 | "minimist": "^1.2.3", 628 | "shelljs": "^0.8.5" 629 | }, 630 | "bin": { 631 | "shx": "lib/cli.js" 632 | }, 633 | "engines": { 634 | "node": ">=6" 635 | } 636 | }, 637 | "node_modules/signal-exit": { 638 | "version": "4.1.0", 639 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 640 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 641 | "license": "ISC", 642 | "engines": { 643 | "node": ">=14" 644 | }, 645 | "funding": { 646 | "url": "https://github.com/sponsors/isaacs" 647 | } 648 | }, 649 | "node_modules/statuses": { 650 | "version": "2.0.1", 651 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 652 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 653 | "license": "MIT", 654 | "engines": { 655 | "node": ">= 0.8" 656 | } 657 | }, 658 | "node_modules/string-width": { 659 | "version": "5.1.2", 660 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 661 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 662 | "license": "MIT", 663 | "dependencies": { 664 | "eastasianwidth": "^0.2.0", 665 | "emoji-regex": "^9.2.2", 666 | "strip-ansi": "^7.0.1" 667 | }, 668 | "engines": { 669 | "node": ">=12" 670 | }, 671 | "funding": { 672 | "url": "https://github.com/sponsors/sindresorhus" 673 | } 674 | }, 675 | "node_modules/string-width-cjs": { 676 | "name": "string-width", 677 | "version": "4.2.3", 678 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 679 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 680 | "license": "MIT", 681 | "dependencies": { 682 | "emoji-regex": "^8.0.0", 683 | "is-fullwidth-code-point": "^3.0.0", 684 | "strip-ansi": "^6.0.1" 685 | }, 686 | "engines": { 687 | "node": ">=8" 688 | } 689 | }, 690 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 691 | "version": "5.0.1", 692 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 693 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 694 | "license": "MIT", 695 | "engines": { 696 | "node": ">=8" 697 | } 698 | }, 699 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 700 | "version": "8.0.0", 701 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 702 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 703 | "license": "MIT" 704 | }, 705 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 706 | "version": "6.0.1", 707 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 708 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 709 | "license": "MIT", 710 | "dependencies": { 711 | "ansi-regex": "^5.0.1" 712 | }, 713 | "engines": { 714 | "node": ">=8" 715 | } 716 | }, 717 | "node_modules/strip-ansi": { 718 | "version": "7.1.0", 719 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 720 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 721 | "license": "MIT", 722 | "dependencies": { 723 | "ansi-regex": "^6.0.1" 724 | }, 725 | "engines": { 726 | "node": ">=12" 727 | }, 728 | "funding": { 729 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 730 | } 731 | }, 732 | "node_modules/strip-ansi-cjs": { 733 | "name": "strip-ansi", 734 | "version": "6.0.1", 735 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 736 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 737 | "license": "MIT", 738 | "dependencies": { 739 | "ansi-regex": "^5.0.1" 740 | }, 741 | "engines": { 742 | "node": ">=8" 743 | } 744 | }, 745 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 746 | "version": "5.0.1", 747 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 748 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 749 | "license": "MIT", 750 | "engines": { 751 | "node": ">=8" 752 | } 753 | }, 754 | "node_modules/supports-preserve-symlinks-flag": { 755 | "version": "1.0.0", 756 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 757 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 758 | "dev": true, 759 | "license": "MIT", 760 | "engines": { 761 | "node": ">= 0.4" 762 | }, 763 | "funding": { 764 | "url": "https://github.com/sponsors/ljharb" 765 | } 766 | }, 767 | "node_modules/toidentifier": { 768 | "version": "1.0.1", 769 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 770 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 771 | "license": "MIT", 772 | "engines": { 773 | "node": ">=0.6" 774 | } 775 | }, 776 | "node_modules/typescript": { 777 | "version": "5.7.2", 778 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 779 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 780 | "dev": true, 781 | "license": "Apache-2.0", 782 | "bin": { 783 | "tsc": "bin/tsc", 784 | "tsserver": "bin/tsserver" 785 | }, 786 | "engines": { 787 | "node": ">=14.17" 788 | } 789 | }, 790 | "node_modules/undici-types": { 791 | "version": "6.19.8", 792 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 793 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 794 | "dev": true, 795 | "license": "MIT" 796 | }, 797 | "node_modules/unpipe": { 798 | "version": "1.0.0", 799 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 800 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 801 | "license": "MIT", 802 | "engines": { 803 | "node": ">= 0.8" 804 | } 805 | }, 806 | "node_modules/which": { 807 | "version": "2.0.2", 808 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 809 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 810 | "license": "ISC", 811 | "dependencies": { 812 | "isexe": "^2.0.0" 813 | }, 814 | "bin": { 815 | "node-which": "bin/node-which" 816 | }, 817 | "engines": { 818 | "node": ">= 8" 819 | } 820 | }, 821 | "node_modules/wrap-ansi": { 822 | "version": "8.1.0", 823 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 824 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 825 | "license": "MIT", 826 | "dependencies": { 827 | "ansi-styles": "^6.1.0", 828 | "string-width": "^5.0.1", 829 | "strip-ansi": "^7.0.1" 830 | }, 831 | "engines": { 832 | "node": ">=12" 833 | }, 834 | "funding": { 835 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 836 | } 837 | }, 838 | "node_modules/wrap-ansi-cjs": { 839 | "name": "wrap-ansi", 840 | "version": "7.0.0", 841 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 842 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 843 | "license": "MIT", 844 | "dependencies": { 845 | "ansi-styles": "^4.0.0", 846 | "string-width": "^4.1.0", 847 | "strip-ansi": "^6.0.0" 848 | }, 849 | "engines": { 850 | "node": ">=10" 851 | }, 852 | "funding": { 853 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 854 | } 855 | }, 856 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 857 | "version": "5.0.1", 858 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 859 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 860 | "license": "MIT", 861 | "engines": { 862 | "node": ">=8" 863 | } 864 | }, 865 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 866 | "version": "4.3.0", 867 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 868 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 869 | "license": "MIT", 870 | "dependencies": { 871 | "color-convert": "^2.0.1" 872 | }, 873 | "engines": { 874 | "node": ">=8" 875 | }, 876 | "funding": { 877 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 878 | } 879 | }, 880 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 881 | "version": "8.0.0", 882 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 883 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 884 | "license": "MIT" 885 | }, 886 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 887 | "version": "4.2.3", 888 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 889 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 890 | "license": "MIT", 891 | "dependencies": { 892 | "emoji-regex": "^8.0.0", 893 | "is-fullwidth-code-point": "^3.0.0", 894 | "strip-ansi": "^6.0.1" 895 | }, 896 | "engines": { 897 | "node": ">=8" 898 | } 899 | }, 900 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 901 | "version": "6.0.1", 902 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 903 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 904 | "license": "MIT", 905 | "dependencies": { 906 | "ansi-regex": "^5.0.1" 907 | }, 908 | "engines": { 909 | "node": ">=8" 910 | } 911 | }, 912 | "node_modules/wrappy": { 913 | "version": "1.0.2", 914 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 915 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 916 | "dev": true, 917 | "license": "ISC" 918 | }, 919 | "node_modules/zod": { 920 | "version": "3.24.1", 921 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", 922 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", 923 | "license": "MIT", 924 | "funding": { 925 | "url": "https://github.com/sponsors/colinhacks" 926 | } 927 | }, 928 | "node_modules/zod-to-json-schema": { 929 | "version": "3.24.1", 930 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz", 931 | "integrity": "sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==", 932 | "license": "ISC", 933 | "peerDependencies": { 934 | "zod": "^3.24.1" 935 | } 936 | } 937 | } 938 | } 939 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kazuph/mcp-taskmanager", 3 | "version": "1.0.2", 4 | "description": "Model Context Protocol server for Task Management", 5 | "author": "kazuph (https://x.com/kazuph)", 6 | "main": "dist/index.js", 7 | "type": "module", 8 | "bin": { 9 | "mcp-taskmanager": "dist/index.js" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "scripts": { 15 | "build": "tsc && shx chmod +x dist/*.js", 16 | "prepare": "npm run build", 17 | "watch": "tsc --watch" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/kazuph/mcp-taskmanager.git" 22 | }, 23 | "keywords": [ 24 | "taskmanager", 25 | "mcp", 26 | "claude" 27 | ], 28 | "license": "MIT", 29 | "publishConfig": { 30 | "access": "public" 31 | }, 32 | "dependencies": { 33 | "@modelcontextprotocol/sdk": "0.5.0", 34 | "chalk": "^5.3.0", 35 | "glob": "^10.3.10", 36 | "zod": "^3.23.8", 37 | "zod-to-json-schema": "^3.23.5" 38 | }, 39 | "devDependencies": { 40 | "@types/json-schema": "^7.0.15", 41 | "@types/node": "^20.11.0", 42 | "shx": "^0.3.4", 43 | "typescript": "^5.3.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@modelcontextprotocol/sdk': 12 | specifier: 0.5.0 13 | version: 0.5.0 14 | chalk: 15 | specifier: ^5.3.0 16 | version: 5.4.1 17 | glob: 18 | specifier: ^10.3.10 19 | version: 10.4.5 20 | zod: 21 | specifier: ^3.23.8 22 | version: 3.24.1 23 | zod-to-json-schema: 24 | specifier: ^3.23.5 25 | version: 3.24.1(zod@3.24.1) 26 | devDependencies: 27 | '@types/json-schema': 28 | specifier: ^7.0.15 29 | version: 7.0.15 30 | '@types/node': 31 | specifier: ^20.11.0 32 | version: 20.17.10 33 | shx: 34 | specifier: ^0.3.4 35 | version: 0.3.4 36 | typescript: 37 | specifier: ^5.3.3 38 | version: 5.7.2 39 | 40 | packages: 41 | 42 | '@isaacs/cliui@8.0.2': 43 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 44 | engines: {node: '>=12'} 45 | 46 | '@modelcontextprotocol/sdk@0.5.0': 47 | resolution: {integrity: sha512-RXgulUX6ewvxjAG0kOpLMEdXXWkzWgaoCGaA2CwNW7cQCIphjpJhjpHSiaPdVCnisjRF/0Cm9KWHUuIoeiAblQ==} 48 | 49 | '@pkgjs/parseargs@0.11.0': 50 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 51 | engines: {node: '>=14'} 52 | 53 | '@types/json-schema@7.0.15': 54 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 55 | 56 | '@types/node@20.17.10': 57 | resolution: {integrity: sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==} 58 | 59 | ansi-regex@5.0.1: 60 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 61 | engines: {node: '>=8'} 62 | 63 | ansi-regex@6.1.0: 64 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} 65 | engines: {node: '>=12'} 66 | 67 | ansi-styles@4.3.0: 68 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 69 | engines: {node: '>=8'} 70 | 71 | ansi-styles@6.2.1: 72 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 73 | engines: {node: '>=12'} 74 | 75 | balanced-match@1.0.2: 76 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 77 | 78 | brace-expansion@1.1.11: 79 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 80 | 81 | brace-expansion@2.0.1: 82 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 83 | 84 | bytes@3.1.2: 85 | resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} 86 | engines: {node: '>= 0.8'} 87 | 88 | chalk@5.4.1: 89 | resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} 90 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 91 | 92 | color-convert@2.0.1: 93 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 94 | engines: {node: '>=7.0.0'} 95 | 96 | color-name@1.1.4: 97 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 98 | 99 | concat-map@0.0.1: 100 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 101 | 102 | content-type@1.0.5: 103 | resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} 104 | engines: {node: '>= 0.6'} 105 | 106 | cross-spawn@7.0.6: 107 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 108 | engines: {node: '>= 8'} 109 | 110 | depd@2.0.0: 111 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 112 | engines: {node: '>= 0.8'} 113 | 114 | eastasianwidth@0.2.0: 115 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 116 | 117 | emoji-regex@8.0.0: 118 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 119 | 120 | emoji-regex@9.2.2: 121 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 122 | 123 | foreground-child@3.3.0: 124 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} 125 | engines: {node: '>=14'} 126 | 127 | fs.realpath@1.0.0: 128 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 129 | 130 | function-bind@1.1.2: 131 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 132 | 133 | glob@10.4.5: 134 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 135 | hasBin: true 136 | 137 | glob@7.2.3: 138 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 139 | deprecated: Glob versions prior to v9 are no longer supported 140 | 141 | hasown@2.0.2: 142 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 143 | engines: {node: '>= 0.4'} 144 | 145 | http-errors@2.0.0: 146 | resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 147 | engines: {node: '>= 0.8'} 148 | 149 | iconv-lite@0.6.3: 150 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 151 | engines: {node: '>=0.10.0'} 152 | 153 | inflight@1.0.6: 154 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 155 | deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 156 | 157 | inherits@2.0.4: 158 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 159 | 160 | interpret@1.4.0: 161 | resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} 162 | engines: {node: '>= 0.10'} 163 | 164 | is-core-module@2.16.1: 165 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 166 | engines: {node: '>= 0.4'} 167 | 168 | is-fullwidth-code-point@3.0.0: 169 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 170 | engines: {node: '>=8'} 171 | 172 | isexe@2.0.0: 173 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 174 | 175 | jackspeak@3.4.3: 176 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 177 | 178 | lru-cache@10.4.3: 179 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 180 | 181 | minimatch@3.1.2: 182 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 183 | 184 | minimatch@9.0.5: 185 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 186 | engines: {node: '>=16 || 14 >=14.17'} 187 | 188 | minimist@1.2.8: 189 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 190 | 191 | minipass@7.1.2: 192 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 193 | engines: {node: '>=16 || 14 >=14.17'} 194 | 195 | once@1.4.0: 196 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 197 | 198 | package-json-from-dist@1.0.1: 199 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} 200 | 201 | path-is-absolute@1.0.1: 202 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 203 | engines: {node: '>=0.10.0'} 204 | 205 | path-key@3.1.1: 206 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 207 | engines: {node: '>=8'} 208 | 209 | path-parse@1.0.7: 210 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 211 | 212 | path-scurry@1.11.1: 213 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 214 | engines: {node: '>=16 || 14 >=14.18'} 215 | 216 | raw-body@3.0.0: 217 | resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} 218 | engines: {node: '>= 0.8'} 219 | 220 | rechoir@0.6.2: 221 | resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} 222 | engines: {node: '>= 0.10'} 223 | 224 | resolve@1.22.10: 225 | resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} 226 | engines: {node: '>= 0.4'} 227 | hasBin: true 228 | 229 | safer-buffer@2.1.2: 230 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 231 | 232 | setprototypeof@1.2.0: 233 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} 234 | 235 | shebang-command@2.0.0: 236 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 237 | engines: {node: '>=8'} 238 | 239 | shebang-regex@3.0.0: 240 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 241 | engines: {node: '>=8'} 242 | 243 | shelljs@0.8.5: 244 | resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} 245 | engines: {node: '>=4'} 246 | hasBin: true 247 | 248 | shx@0.3.4: 249 | resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==} 250 | engines: {node: '>=6'} 251 | hasBin: true 252 | 253 | signal-exit@4.1.0: 254 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 255 | engines: {node: '>=14'} 256 | 257 | statuses@2.0.1: 258 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 259 | engines: {node: '>= 0.8'} 260 | 261 | string-width@4.2.3: 262 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 263 | engines: {node: '>=8'} 264 | 265 | string-width@5.1.2: 266 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 267 | engines: {node: '>=12'} 268 | 269 | strip-ansi@6.0.1: 270 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 271 | engines: {node: '>=8'} 272 | 273 | strip-ansi@7.1.0: 274 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 275 | engines: {node: '>=12'} 276 | 277 | supports-preserve-symlinks-flag@1.0.0: 278 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 279 | engines: {node: '>= 0.4'} 280 | 281 | toidentifier@1.0.1: 282 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 283 | engines: {node: '>=0.6'} 284 | 285 | typescript@5.7.2: 286 | resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} 287 | engines: {node: '>=14.17'} 288 | hasBin: true 289 | 290 | undici-types@6.19.8: 291 | resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} 292 | 293 | unpipe@1.0.0: 294 | resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 295 | engines: {node: '>= 0.8'} 296 | 297 | which@2.0.2: 298 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 299 | engines: {node: '>= 8'} 300 | hasBin: true 301 | 302 | wrap-ansi@7.0.0: 303 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 304 | engines: {node: '>=10'} 305 | 306 | wrap-ansi@8.1.0: 307 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 308 | engines: {node: '>=12'} 309 | 310 | wrappy@1.0.2: 311 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 312 | 313 | zod-to-json-schema@3.24.1: 314 | resolution: {integrity: sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==} 315 | peerDependencies: 316 | zod: ^3.24.1 317 | 318 | zod@3.24.1: 319 | resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} 320 | 321 | snapshots: 322 | 323 | '@isaacs/cliui@8.0.2': 324 | dependencies: 325 | string-width: 5.1.2 326 | string-width-cjs: string-width@4.2.3 327 | strip-ansi: 7.1.0 328 | strip-ansi-cjs: strip-ansi@6.0.1 329 | wrap-ansi: 8.1.0 330 | wrap-ansi-cjs: wrap-ansi@7.0.0 331 | 332 | '@modelcontextprotocol/sdk@0.5.0': 333 | dependencies: 334 | content-type: 1.0.5 335 | raw-body: 3.0.0 336 | zod: 3.24.1 337 | 338 | '@pkgjs/parseargs@0.11.0': 339 | optional: true 340 | 341 | '@types/json-schema@7.0.15': {} 342 | 343 | '@types/node@20.17.10': 344 | dependencies: 345 | undici-types: 6.19.8 346 | 347 | ansi-regex@5.0.1: {} 348 | 349 | ansi-regex@6.1.0: {} 350 | 351 | ansi-styles@4.3.0: 352 | dependencies: 353 | color-convert: 2.0.1 354 | 355 | ansi-styles@6.2.1: {} 356 | 357 | balanced-match@1.0.2: {} 358 | 359 | brace-expansion@1.1.11: 360 | dependencies: 361 | balanced-match: 1.0.2 362 | concat-map: 0.0.1 363 | 364 | brace-expansion@2.0.1: 365 | dependencies: 366 | balanced-match: 1.0.2 367 | 368 | bytes@3.1.2: {} 369 | 370 | chalk@5.4.1: {} 371 | 372 | color-convert@2.0.1: 373 | dependencies: 374 | color-name: 1.1.4 375 | 376 | color-name@1.1.4: {} 377 | 378 | concat-map@0.0.1: {} 379 | 380 | content-type@1.0.5: {} 381 | 382 | cross-spawn@7.0.6: 383 | dependencies: 384 | path-key: 3.1.1 385 | shebang-command: 2.0.0 386 | which: 2.0.2 387 | 388 | depd@2.0.0: {} 389 | 390 | eastasianwidth@0.2.0: {} 391 | 392 | emoji-regex@8.0.0: {} 393 | 394 | emoji-regex@9.2.2: {} 395 | 396 | foreground-child@3.3.0: 397 | dependencies: 398 | cross-spawn: 7.0.6 399 | signal-exit: 4.1.0 400 | 401 | fs.realpath@1.0.0: {} 402 | 403 | function-bind@1.1.2: {} 404 | 405 | glob@10.4.5: 406 | dependencies: 407 | foreground-child: 3.3.0 408 | jackspeak: 3.4.3 409 | minimatch: 9.0.5 410 | minipass: 7.1.2 411 | package-json-from-dist: 1.0.1 412 | path-scurry: 1.11.1 413 | 414 | glob@7.2.3: 415 | dependencies: 416 | fs.realpath: 1.0.0 417 | inflight: 1.0.6 418 | inherits: 2.0.4 419 | minimatch: 3.1.2 420 | once: 1.4.0 421 | path-is-absolute: 1.0.1 422 | 423 | hasown@2.0.2: 424 | dependencies: 425 | function-bind: 1.1.2 426 | 427 | http-errors@2.0.0: 428 | dependencies: 429 | depd: 2.0.0 430 | inherits: 2.0.4 431 | setprototypeof: 1.2.0 432 | statuses: 2.0.1 433 | toidentifier: 1.0.1 434 | 435 | iconv-lite@0.6.3: 436 | dependencies: 437 | safer-buffer: 2.1.2 438 | 439 | inflight@1.0.6: 440 | dependencies: 441 | once: 1.4.0 442 | wrappy: 1.0.2 443 | 444 | inherits@2.0.4: {} 445 | 446 | interpret@1.4.0: {} 447 | 448 | is-core-module@2.16.1: 449 | dependencies: 450 | hasown: 2.0.2 451 | 452 | is-fullwidth-code-point@3.0.0: {} 453 | 454 | isexe@2.0.0: {} 455 | 456 | jackspeak@3.4.3: 457 | dependencies: 458 | '@isaacs/cliui': 8.0.2 459 | optionalDependencies: 460 | '@pkgjs/parseargs': 0.11.0 461 | 462 | lru-cache@10.4.3: {} 463 | 464 | minimatch@3.1.2: 465 | dependencies: 466 | brace-expansion: 1.1.11 467 | 468 | minimatch@9.0.5: 469 | dependencies: 470 | brace-expansion: 2.0.1 471 | 472 | minimist@1.2.8: {} 473 | 474 | minipass@7.1.2: {} 475 | 476 | once@1.4.0: 477 | dependencies: 478 | wrappy: 1.0.2 479 | 480 | package-json-from-dist@1.0.1: {} 481 | 482 | path-is-absolute@1.0.1: {} 483 | 484 | path-key@3.1.1: {} 485 | 486 | path-parse@1.0.7: {} 487 | 488 | path-scurry@1.11.1: 489 | dependencies: 490 | lru-cache: 10.4.3 491 | minipass: 7.1.2 492 | 493 | raw-body@3.0.0: 494 | dependencies: 495 | bytes: 3.1.2 496 | http-errors: 2.0.0 497 | iconv-lite: 0.6.3 498 | unpipe: 1.0.0 499 | 500 | rechoir@0.6.2: 501 | dependencies: 502 | resolve: 1.22.10 503 | 504 | resolve@1.22.10: 505 | dependencies: 506 | is-core-module: 2.16.1 507 | path-parse: 1.0.7 508 | supports-preserve-symlinks-flag: 1.0.0 509 | 510 | safer-buffer@2.1.2: {} 511 | 512 | setprototypeof@1.2.0: {} 513 | 514 | shebang-command@2.0.0: 515 | dependencies: 516 | shebang-regex: 3.0.0 517 | 518 | shebang-regex@3.0.0: {} 519 | 520 | shelljs@0.8.5: 521 | dependencies: 522 | glob: 7.2.3 523 | interpret: 1.4.0 524 | rechoir: 0.6.2 525 | 526 | shx@0.3.4: 527 | dependencies: 528 | minimist: 1.2.8 529 | shelljs: 0.8.5 530 | 531 | signal-exit@4.1.0: {} 532 | 533 | statuses@2.0.1: {} 534 | 535 | string-width@4.2.3: 536 | dependencies: 537 | emoji-regex: 8.0.0 538 | is-fullwidth-code-point: 3.0.0 539 | strip-ansi: 6.0.1 540 | 541 | string-width@5.1.2: 542 | dependencies: 543 | eastasianwidth: 0.2.0 544 | emoji-regex: 9.2.2 545 | strip-ansi: 7.1.0 546 | 547 | strip-ansi@6.0.1: 548 | dependencies: 549 | ansi-regex: 5.0.1 550 | 551 | strip-ansi@7.1.0: 552 | dependencies: 553 | ansi-regex: 6.1.0 554 | 555 | supports-preserve-symlinks-flag@1.0.0: {} 556 | 557 | toidentifier@1.0.1: {} 558 | 559 | typescript@5.7.2: {} 560 | 561 | undici-types@6.19.8: {} 562 | 563 | unpipe@1.0.0: {} 564 | 565 | which@2.0.2: 566 | dependencies: 567 | isexe: 2.0.0 568 | 569 | wrap-ansi@7.0.0: 570 | dependencies: 571 | ansi-styles: 4.3.0 572 | string-width: 4.2.3 573 | strip-ansi: 6.0.1 574 | 575 | wrap-ansi@8.1.0: 576 | dependencies: 577 | ansi-styles: 6.2.1 578 | string-width: 5.1.2 579 | strip-ansi: 7.1.0 580 | 581 | wrappy@1.0.2: {} 582 | 583 | zod-to-json-schema@3.24.1(zod@3.24.1): 584 | dependencies: 585 | zod: 3.24.1 586 | 587 | zod@3.24.1: {} 588 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "strict": true, 5 | "esModuleInterop": true, 6 | "skipLibCheck": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "outDir": "./dist", 10 | "rootDir": ".", 11 | "moduleResolution": "NodeNext", 12 | "module": "NodeNext" 13 | }, 14 | "exclude": ["node_modules"], 15 | "include": ["./**/*.ts"] 16 | } 17 | --------------------------------------------------------------------------------