roadmap-skill 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +14 -32
- package/README.zh.md +15 -24
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.11] - 2026-03-09
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **MCP Prompts**: Added non-intrusive task hints to `open-web-ui` and `quick-capture` prompts
|
|
12
|
+
- **Port Display**: Fixed NaN display when port parameter is not provided in `open-web-ui` prompt
|
|
13
|
+
- **Prompt Wording**: Removed command-like phrasing that could be misidentified as injection attempts
|
|
14
|
+
|
|
15
|
+
|
|
8
16
|
## [0.2.10] - 2026-02-27
|
|
9
17
|
|
|
10
18
|
### Added
|
package/README.md
CHANGED
|
@@ -290,28 +290,25 @@ Solo developers, AI power users, and vibe coders who want their Agent to be a re
|
|
|
290
290
|
|
|
291
291
|
### 1. Capture Ideas Without Breaking Flow
|
|
292
292
|
|
|
293
|
-
Mid-session, something
|
|
293
|
+
Mid-session, something pops into your head:
|
|
294
294
|
|
|
295
295
|
> "Note this down: switch the auth module to JWT + refresh token rotation"
|
|
296
296
|
|
|
297
|
-
|
|
297
|
+
Use `/quick-capture` or just say "help me note this down" — your Agent turns it into a task, saves it locally, and you keep going. No context switch, no forgotten ideas.
|
|
298
298
|
|
|
299
|
-
### 2. Let
|
|
299
|
+
### 2. Let Agent Help You Prioritize
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
> "This month's OKR is finishing the user system refactor — can you list the related tasks and figure out which ones should come first?"
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
Use `/auto-prioritize` to let your Agent analyze the current project state and reorder task priorities accordingly.
|
|
304
304
|
|
|
305
|
-
|
|
305
|
+
### 3. Let Agent Recommend What to Do Next
|
|
306
306
|
|
|
307
|
-
|
|
307
|
+
> "What's left on the current project? Any high-priority tasks I haven't touched yet?"
|
|
308
308
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
> "Mark the login feature done and add a task for writing tests."
|
|
309
|
+
Or use `/suggest-tasks` — your Agent recommends the next actions based on current progress and priorities.
|
|
312
310
|
|
|
313
311
|
No tab switching. No copy-pasting. Just ask.
|
|
314
|
-
|
|
315
312
|
---
|
|
316
313
|
|
|
317
314
|
## Core Features
|
|
@@ -328,10 +325,8 @@ No tab switching. No copy-pasting. Just ask.
|
|
|
328
325
|
|
|
329
326
|
## Supported Platforms
|
|
330
327
|
|
|
331
|
-
- ✅ **Claude Code** — Command-line AI
|
|
332
|
-
- ✅ **
|
|
333
|
-
- ✅ **Cursor** — AI-powered IDE
|
|
334
|
-
- ✅ **VS Code** — Via Cline or Roo Code extensions
|
|
328
|
+
- ✅ **Claude Code, Codex, OpenCode** — Command-line AI assistants
|
|
329
|
+
- ✅ **Cursor, VS Code** — AI-powered IDEs
|
|
335
330
|
- ✅ **Any MCP Client** — Standard MCP protocol support
|
|
336
331
|
|
|
337
332
|
---
|
|
@@ -342,24 +337,11 @@ Roadmap Skill uses **pure local JSON file storage**. All data is saved in your u
|
|
|
342
337
|
|
|
343
338
|
| Platform | Storage Path |
|
|
344
339
|
|---------|-------------|
|
|
345
|
-
|
|
|
346
|
-
|
|
|
347
|
-
|
|
|
348
|
-
|
|
349
|
-
### Data File Structure
|
|
350
|
-
|
|
351
|
-
```
|
|
352
|
-
.roadmap-skill/
|
|
353
|
-
└── data/
|
|
354
|
-
├── projects.json # Project list
|
|
355
|
-
├── tasks.json # All tasks
|
|
356
|
-
└── tags.json # Tag definitions
|
|
357
|
-
```
|
|
340
|
+
| Windows | `%USERPROFILE%\.roadmap-skill` |
|
|
341
|
+
| macOS | `~/.roadmap-skill/` |
|
|
342
|
+
| Linux | `~/.roadmap-skill/` |
|
|
358
343
|
|
|
359
|
-
|
|
360
|
-
- ✅ **Portable** — Copy folder to backup/transfer
|
|
361
|
-
- ✅ **Version control friendly** — JSON format for easy diff
|
|
362
|
-
- ✅ **Privacy secure** — Data never leaves your machine
|
|
344
|
+
You can export or import backup files from the web interface.
|
|
363
345
|
|
|
364
346
|
---
|
|
365
347
|
|
package/README.zh.md
CHANGED
|
@@ -285,25 +285,23 @@ AI 会立即为你创建项目和任务,并自动写入本地存储。你可
|
|
|
285
285
|
|
|
286
286
|
### 1. 不打断流地记录想法
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
VibeCoding时,突然想到一个新idea/有新Bug:
|
|
289
289
|
|
|
290
290
|
> "记一下:把认证模块改成 JWT + refresh token 方案"
|
|
291
291
|
|
|
292
|
-
Agent
|
|
292
|
+
直接使用 `/quick-capture` 命令,或者直接说“帮我记一下”,Agent 就会把这个想法变成一个项目的代办,保存在本地,然后继续工作。等有空了再回来看,任务已经在那里了,不用担心忘记,也不用打断当前的思路去切换工具。
|
|
293
293
|
|
|
294
|
-
### 2. 让
|
|
294
|
+
### 2. 让 Agent 帮你划分任务优先级
|
|
295
295
|
|
|
296
|
-
|
|
296
|
+
> "这个月的 OKR 是完成用户系统重构,能不能帮我把相关的任务都列出来,并且分析一下哪些任务应该有限做?"
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
直接使用 `/auto-prioritize` 命令,让 Agent 根据当前的项目状态,给已有的任务合理调整优先级。
|
|
299
299
|
|
|
300
|
-
Agent
|
|
301
|
-
|
|
302
|
-
### 3. 不离开对话窗口就能检查进度
|
|
300
|
+
### 3. 让 Agent 自动给你推荐接下来做什么
|
|
303
301
|
|
|
304
302
|
> "当前项目还剩什么?有没有高优先级的任务还没动?"
|
|
305
303
|
|
|
306
|
-
|
|
304
|
+
或者直接使用 `/suggest-tasks` 命令,让 Agent 根据当前进度和优先级给你推荐下一步行动。
|
|
307
305
|
|
|
308
306
|
不用切换标签页,不用复制粘贴。直接问就行。
|
|
309
307
|
|
|
@@ -335,24 +333,17 @@ Roadmap Skill 采用**纯本地 JSON 文件存储**,所有数据保存在你
|
|
|
335
333
|
|
|
336
334
|
| 平台 | 存储路径 |
|
|
337
335
|
|------|---------|
|
|
338
|
-
|
|
|
339
|
-
|
|
|
340
|
-
|
|
|
336
|
+
| Windows | `%USERPROFILE%\.roadmap-skill` |
|
|
337
|
+
| macOS | `~/.roadmap-skill/` |
|
|
338
|
+
| Linux | `~/.roadmap-skill/` |
|
|
341
339
|
|
|
342
|
-
|
|
340
|
+
你可以在前端界面中选择导出/导入备份文件。
|
|
343
341
|
|
|
344
|
-
|
|
345
|
-
.roadmap-skill/
|
|
346
|
-
└── data/
|
|
347
|
-
├── projects.json # 项目列表
|
|
348
|
-
├── tasks.json # 所有任务
|
|
349
|
-
└── tags.json # 标签定义
|
|
350
|
-
```
|
|
342
|
+
---
|
|
351
343
|
|
|
352
|
-
|
|
353
|
-
-
|
|
354
|
-
|
|
355
|
-
- ✅ **隐私安全** — 数据永远不会离开你的电脑
|
|
344
|
+
## 参与贡献
|
|
345
|
+
欢迎任何形式的贡献!无论是 Bug 反馈、功能建议还是 Pull Request,都可以直接在 [GitHub](https://github.com/shiquda/roadmap-skill) 上提 Issue 或 PR。
|
|
346
|
+
如果你想添加新功能,建议先开 Issue 讨论一下方向。
|
|
356
347
|
|
|
357
348
|
---
|
|
358
349
|
|
package/dist/index.js
CHANGED
|
@@ -2541,6 +2541,8 @@ function getQuickCapturePrompt(idea, projectId) {
|
|
|
2541
2541
|
|
|
2542
2542
|
${projectContext}
|
|
2543
2543
|
|
|
2544
|
+
## [Non-intrusive task] Pause your current work briefly to complete this quick capture, then let the user know it's done and resume what you were doing.
|
|
2545
|
+
|
|
2544
2546
|
## Please complete the following steps immediately:
|
|
2545
2547
|
|
|
2546
2548
|
### 1. Task Information Extraction
|
|
@@ -2609,7 +2611,9 @@ function getOpenWebUIPrompt(port) {
|
|
|
2609
2611
|
role: "user",
|
|
2610
2612
|
content: {
|
|
2611
2613
|
type: "text",
|
|
2612
|
-
text:
|
|
2614
|
+
text: `**[Non-intrusive task]** Pause your current work briefly to complete this quick action, then let the user know it's done and resume what you were doing.
|
|
2615
|
+
|
|
2616
|
+
Call the open_web_interface tool${port ? ` with port ${portNum}` : ""} to launch the roadmap-skill web visualization interface.`
|
|
2613
2617
|
}
|
|
2614
2618
|
}
|
|
2615
2619
|
]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/file-helpers.ts","../src/index.ts","../src/server.ts","../src/tools/index.ts","../src/tools/project-tools.ts","../src/storage/index.ts","../src/utils/path-helpers.ts","../src/tools/task-tools.ts","../src/services/index.ts","../src/services/tag-service.ts","../src/services/task-service.ts","../src/services/types.ts","../src/tools/tag-tools.ts","../src/tools/web-tools.ts","../src/web/server.ts","../src/tools/template-tools.ts","../src/resources/index.ts","../src/resources/project-resources.ts","../src/prompts/index.ts","../src/prompts/project-prompts.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import * as fs from 'fs/promises';\n\n/**\n * Read and parse a JSON file\n * @param filePath - Path to the JSON file\n * @returns Parsed JSON data\n * @throws Error if file cannot be read or parsed\n */\nexport async function readJsonFile<T>(filePath: string): Promise<T> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to read JSON file ${filePath}: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Write data to a JSON file\n * @param filePath - Path to the JSON file\n * @param data - Data to serialize and write\n * @throws Error if file cannot be written\n */\nexport async function writeJsonFile<T>(filePath: string, data: T): Promise<void> {\n try {\n const content = JSON.stringify(data, null, 2);\n await fs.writeFile(filePath, content, 'utf-8');\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to write JSON file ${filePath}: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Ensure a directory exists, creating it recursively if needed\n * @param dirPath - Path to the directory\n * @throws Error if directory cannot be created\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to create directory ${dirPath}: ${error.message}`);\n }\n throw error;\n }\n}\n","import { startServer } from './server.js';\n\nasync function main() {\n process.on('SIGINT', () => {\n console.error('Received SIGINT, shutting down gracefully...');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.error('Received SIGTERM, shutting down gracefully...');\n process.exit(0);\n });\n\n process.on('uncaughtException', (error) => {\n console.error('Uncaught exception:', error);\n // Do not exit — keep MCP stdio transport alive\n });\n\n process.on('unhandledRejection', (reason) => {\n console.error('Unhandled rejection:', reason);\n // Do not exit — keep MCP stdio transport alive\n });\n\n try {\n await startServer();\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\nmain();\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n\tCallToolRequestSchema,\n\tListToolsRequestSchema,\n\tListResourcesRequestSchema,\n\tReadResourceRequestSchema,\n\tListPromptsRequestSchema,\n\tGetPromptRequestSchema,\n\ttype CallToolRequest,\n\ttype ListToolsRequest,\n\ttype ListResourcesRequest,\n\ttype ReadResourceRequest,\n\ttype ListPromptsRequest,\n\ttype GetPromptRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nimport {\n\tcreateProjectTool,\n\tlistProjectsTool,\n\tgetProjectTool,\n\tupdateProjectTool,\n\tdeleteProjectTool,\n\tcreateTaskTool,\n\tlistTasksTool,\n\tgetTaskTool,\n\tupdateTaskTool,\n\tdeleteTaskTool,\n\tbatchUpdateTasksTool,\n\tcreateTagTool,\n\tlistTagsTool,\n\tupdateTagTool,\n\tdeleteTagTool,\n\tgetTasksByTagTool,\n\topenWebInterfaceTool,\n\tcloseWebInterfaceTool,\n} from \"./tools/index.js\";\nimport { getAllResources, handleResourceRequest } from \"./resources/index.js\";\nimport { getAllPrompts, getPromptByName } from \"./prompts/index.js\";\n\nconst allTools = [\n\tcreateProjectTool,\n\tlistProjectsTool,\n\tgetProjectTool,\n\tupdateProjectTool,\n\tdeleteProjectTool,\n\tcreateTaskTool,\n\tlistTasksTool,\n\tgetTaskTool,\n\tupdateTaskTool,\n\tdeleteTaskTool,\n\tbatchUpdateTasksTool,\n\tcreateTagTool,\n\tlistTagsTool,\n\tupdateTagTool,\n\tdeleteTagTool,\n\tgetTasksByTagTool,\n\topenWebInterfaceTool,\n\tcloseWebInterfaceTool,\n];\n\nconst toolMap = new Map(allTools.map((tool) => [tool.name, tool]));\n\nexport function createServer(): Server {\n\tconst server = new Server(\n\t\t{\n\t\t\tname: \"roadmap-skill\",\n\t\t\tversion: \"0.2.1\",\n\t\t},\n\t\t{\n\t\t\tcapabilities: {\n\t\t\t\ttools: {},\n\t\t\t\tresources: {},\n\t\t\t\tprompts: {},\n\t\t\t},\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListToolsRequestSchema,\n\t\tasync (_request: ListToolsRequest) => {\n\t\t\treturn {\n\t\t\t\ttools: allTools.map((tool) => {\n\t\t\t\t\tconst rawSchema =\n\t\t\t\t\t\t(tool as any).parameters || (tool as any).inputSchema;\n\t\t\t\t\tlet inputSchema: Record<string, unknown>;\n\n\t\t\t\t\tif (!rawSchema) {\n\t\t\t\t\t\tinputSchema = { type: \"object\" };\n\t\t\t\t\t} else if (rawSchema.type === \"object\") {\n\t\t\t\t\t\tinputSchema = rawSchema;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinputSchema = zodToJsonSchema(rawSchema, {\n\t\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t\t$refStrategy: \"none\",\n\t\t\t\t\t\t}).definitions?.[tool.name] || { type: \"object\" };\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tinputSchema,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tCallToolRequestSchema,\n\t\tasync (request: CallToolRequest) => {\n\t\t\tconst { name, arguments: args } = request.params;\n\t\t\tconst tool = toolMap.get(name);\n\n\t\t\tif (!tool) {\n\t\t\t\tthrow new Error(`Unknown tool: ${name}`);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await tool.execute(args as never);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: JSON.stringify(result, null, 2),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n } catch (error) {\n\t\t\t\tconst errorMessage =\n\t\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `Tool execution failed: ${errorMessage}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListResourcesRequestSchema,\n\t\tasync (_request: ListResourcesRequest) => {\n\t\t\tconst resources = getAllResources();\n\t\t\treturn { resources };\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tReadResourceRequestSchema,\n\t\tasync (request: ReadResourceRequest) => {\n\t\t\tconst uri = request.params.uri;\n\t\t\tconst resourceContent = await handleResourceRequest(uri);\n\n\t\t\tif (!resourceContent) {\n\t\t\t\tthrow new Error(`Resource not found: ${uri}`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontents: [resourceContent],\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListPromptsRequestSchema,\n\t\tasync (_request: ListPromptsRequest) => {\n\t\t\tconst prompts = getAllPrompts();\n\t\t\treturn { prompts };\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tGetPromptRequestSchema,\n\t\tasync (request: GetPromptRequest) => {\n\t\t\tconst { name, arguments: args } = request.params;\n\t\t\tconst promptResult = getPromptByName(\n\t\t\t\tname,\n\t\t\t\targs as Record<string, string> | undefined,\n\t\t\t);\n\n\t\t\tif (!promptResult) {\n\t\t\t\tthrow new Error(`Prompt not found: ${name}`);\n\t\t\t}\n\n\t\t\treturn promptResult;\n\t\t},\n\t);\n\n\treturn server;\n}\n\nexport async function startServer(): Promise<void> {\n\tconst server = createServer();\n\tconst transport = new StdioServerTransport();\n\n\tconsole.error(\"Roadmap Skill MCP Server starting...\");\n\n\ttry {\n\t\tawait server.connect(transport);\n\t\tconsole.error(\"Roadmap Skill MCP Server connected and ready\");\n\t} catch (error) {\n\t\tconsole.error(\"Failed to start server:\", error);\n\t\tthrow error;\n\t}\n}\n","export {\n createProjectTool,\n listProjectsTool,\n getProjectTool,\n updateProjectTool,\n deleteProjectTool,\n} from './project-tools.js';\n\nexport {\n createTaskTool,\n listTasksTool,\n getTaskTool,\n updateTaskTool,\n deleteTaskTool,\n batchUpdateTasksTool,\n} from './task-tools.js';\n\nexport {\n createTagTool,\n listTagsTool,\n updateTagTool,\n deleteTagTool,\n getTasksByTagTool,\n} from './tag-tools.js';\n\nexport {\n openWebInterfaceTool,\n closeWebInterfaceTool,\n} from './web-tools.js';\n\nexport {\n listTemplatesTool,\n getTemplateTool,\n applyTemplateTool,\n} from './template-tools.js';\n","import { z } from 'zod';\nimport { storage } from '../storage/index.js';\nimport type { Project, ProjectSummary, Task, TaskSummary, CreateProjectInput, UpdateProjectInput } from '../models/index.js';\n\nconst ProjectTypeEnum = z.enum(['roadmap', 'skill-tree', 'kanban']);\nconst ProjectStatusEnum = z.enum(['active', 'completed', 'archived']);\n\nfunction toProjectSummary(\n project: Project,\n taskCount: number,\n tags?: Array<{ id: string; name: string; color: string }>\n): ProjectSummary {\n return {\n id: project.id,\n name: project.name,\n projectType: project.projectType,\n status: project.status,\n targetDate: project.targetDate,\n taskCount,\n ...(tags ? { tags } : {}),\n };\n}\n\nfunction toTaskSummary(task: Task): TaskSummary {\n return {\n id: task.id,\n title: task.title,\n status: task.status,\n priority: task.priority,\n dueDate: task.dueDate,\n assignee: task.assignee,\n tags: task.tags,\n };\n}\n\nexport const createProjectTool = {\n name: 'create_project',\n description: 'Create a new project roadmap. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n name: z.string().min(1, 'Project name is required'),\n description: z.string(),\n projectType: ProjectTypeEnum,\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format'),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n name: string;\n description: string;\n projectType: 'roadmap' | 'skill-tree' | 'kanban';\n startDate: string;\n targetDate: string;\n verbose?: boolean;\n }) {\n try {\n const projectInput: CreateProjectInput = {\n name: input.name,\n description: input.description,\n projectType: input.projectType,\n startDate: input.startDate,\n targetDate: input.targetDate,\n };\n const projectData = await storage.createProject(projectInput);\n return {\n success: true,\n data: input.verbose\n ? projectData\n : toProjectSummary(projectData.project, 0),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create project',\n };\n }\n },\n};\n\nexport const listProjectsTool = {\n name: 'list_projects',\n description: 'List all projects. Summary mode includes current project tags for Agent reuse. Set verbose=true for full project data.',\n inputSchema: z.object({\n verbose: z.boolean().optional(),\n }),\n async execute(input: { verbose?: boolean }) {\n try {\n const projects = await storage.listProjects();\n\n if (input.verbose) {\n return {\n success: true,\n data: projects,\n };\n }\n\n const summaries = await Promise.all(\n projects.map(async (projectSummary) => {\n const projectData = await storage.readProject(projectSummary.project.id);\n const tags = (projectData?.tags ?? []).map((tag) => ({\n id: tag.id,\n name: tag.name,\n color: tag.color,\n }));\n\n return toProjectSummary(projectSummary.project, projectSummary.taskCount, tags);\n })\n );\n\n return {\n success: true,\n data: summaries,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list projects',\n };\n }\n },\n};\n\nexport const getProjectTool = {\n name: 'get_project',\n description: 'Get a project by ID with all its data (tasks, tags, milestones). Tasks are returned as summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: { projectId: string; verbose?: boolean }) {\n try {\n const projectData = await storage.readProject(input.projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${input.projectId}' not found`,\n };\n }\n return {\n success: true,\n data: input.verbose\n ? projectData\n : {\n ...projectData,\n tasks: projectData.tasks.map(toTaskSummary),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get project',\n };\n }\n },\n};\n\nexport const updateProjectTool = {\n name: 'update_project',\n description: 'Update an existing project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n name: z.string().min(1).optional(),\n description: z.string().optional(),\n projectType: ProjectTypeEnum.optional(),\n status: ProjectStatusEnum.optional(),\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n name?: string;\n description?: string;\n projectType?: 'roadmap' | 'skill-tree' | 'kanban';\n status?: 'active' | 'completed' | 'archived';\n startDate?: string;\n targetDate?: string;\n verbose?: boolean;\n }) {\n try {\n const { projectId, verbose, ...updateData } = input;\n if (Object.keys(updateData).length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n };\n }\n const updateInput: UpdateProjectInput = updateData;\n const projectData = await storage.updateProject(projectId, updateInput);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n };\n }\n return {\n success: true,\n data: verbose\n ? projectData\n : toProjectSummary(projectData.project, projectData.tasks.length),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update project',\n };\n }\n },\n};\n\nexport const deleteProjectTool = {\n name: 'delete_project',\n description: 'Delete a project by ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n }),\n async execute(input: { projectId: string }) {\n try {\n const deleted = await storage.deleteProject(input.projectId);\n\n if (!deleted) {\n return {\n success: false,\n error: `Project with ID '${input.projectId}' not found`,\n };\n }\n\n return {\n success: true,\n data: { deleted: true },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete project',\n };\n }\n },\n};\n","import * as path from 'path';\nimport type {\n Project,\n ProjectData,\n Task,\n TaskSearchFilters,\n CreateProjectInput,\n UpdateProjectInput,\n} from '../models/index.js';\nimport { getStorageDir } from '../utils/path-helpers.js';\nimport { readJsonFile, writeJsonFile, ensureDir } from '../utils/file-helpers.js';\n\n/**\n * Storage class for managing roadmap-skill projects\n * Projects are stored as individual JSON files in ~/.roadmap-skill/projects/\n */\nexport class ProjectStorage {\n private storageDir: string;\n\n constructor() {\n this.storageDir = getStorageDir();\n }\n\n /**\n * Ensure the storage directory exists\n */\n async ensureDirectory(): Promise<void> {\n await ensureDir(this.storageDir);\n }\n\n /**\n * Get the file path for a project\n * @param projectId - The project ID\n * @returns Full path to the project JSON file\n */\n getFilePath(projectId: string): string {\n return path.join(this.storageDir, `${projectId}.json`);\n }\n\n /**\n * Create a new project\n * @param input - Project creation data\n * @returns The created project data\n */\n async createProject(input: CreateProjectInput): Promise<ProjectData> {\n await this.ensureDirectory();\n\n const now = new Date().toISOString();\n const projectId = `proj_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n const project: Project = {\n id: projectId,\n name: input.name,\n description: input.description,\n projectType: input.projectType,\n status: 'active',\n startDate: input.startDate,\n targetDate: input.targetDate,\n createdAt: now,\n updatedAt: now,\n };\n\n const projectData: ProjectData = {\n version: 1,\n project,\n milestones: [],\n tasks: [],\n tags: [],\n };\n\n const filePath = this.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return projectData;\n }\n\n /**\n * Read a project by ID\n * @param projectId - The project ID\n * @returns The project data or null if not found\n */\n async readProject(projectId: string): Promise<ProjectData | null> {\n try {\n const filePath = this.getFilePath(projectId);\n return await readJsonFile<ProjectData>(filePath);\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Update an existing project\n * @param projectId - The project ID\n * @param input - Project update data\n * @returns The updated project data or null if not found\n */\n async updateProject(\n projectId: string,\n input: UpdateProjectInput\n ): Promise<ProjectData | null> {\n const projectData = await this.readProject(projectId);\n if (!projectData) {\n return null;\n }\n\n const now = new Date().toISOString();\n\n projectData.project = {\n ...projectData.project,\n ...input,\n updatedAt: now,\n };\n\n const filePath = this.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return projectData;\n }\n\n /**\n * Delete a project by ID\n * @param projectId - The project ID\n * @returns True if deleted, false if not found\n */\n async deleteProject(projectId: string): Promise<boolean> {\n try {\n const filePath = this.getFilePath(projectId);\n const fs = await import('fs/promises');\n await fs.unlink(filePath);\n return true;\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * List all projects sorted by updatedAt (descending)\n * @returns Array of project summaries (project + metadata)\n */\n async listProjects(): Promise<Array<{ project: Project; taskCount: number; milestoneCount: number }>> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const projects: Array<{ project: Project; taskCount: number; milestoneCount: number }> = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n projects.push({\n project: data.project,\n taskCount: data.tasks.length,\n milestoneCount: data.milestones.length,\n });\n } catch {\n // Skip invalid files\n continue;\n }\n }\n\n // Sort by updatedAt descending\n return projects.sort(\n (a, b) => new Date(b.project.updatedAt).getTime() - new Date(a.project.updatedAt).getTime()\n );\n }\n\n /**\n * Search tasks across all projects with filters\n * @param filters - Search filters\n * @returns Array of matching tasks with project context\n */\n async searchTasks(\n filters: TaskSearchFilters\n ): Promise<Array<{ task: Task; project: Project }>> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const results: Array<{ task: Task; project: Project }> = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n\n // Skip if project filter doesn't match\n if (filters.projectId && data.project.id !== filters.projectId) {\n continue;\n }\n\n for (const task of data.tasks) {\n // Apply filters\n if (filters.status && task.status !== filters.status) {\n continue;\n }\n if (filters.priority && task.priority !== filters.priority) {\n continue;\n }\n if (filters.assignee && task.assignee !== filters.assignee) {\n continue;\n }\n if (filters.dueBefore && task.dueDate && task.dueDate > filters.dueBefore) {\n continue;\n }\n if (filters.dueAfter && task.dueDate && task.dueDate < filters.dueAfter) {\n continue;\n }\n if (\n filters.tags &&\n filters.tags.length > 0 &&\n !filters.tags.some((tag) => task.tags.includes(tag))\n ) {\n continue;\n }\n if (\n filters.searchText &&\n !task.title.toLowerCase().includes(filters.searchText.toLowerCase()) &&\n !task.description.toLowerCase().includes(filters.searchText.toLowerCase())\n ) {\n continue;\n }\n\n // Filter completed tasks (done status) unless includeCompleted is explicitly true\n if (filters.includeCompleted !== true && task.status === 'done') {\n continue;\n }\n\n results.push({ task, project: data.project });\n }\n } catch {\n // Skip invalid files\n continue;\n }\n }\n\n return results;\n }\n\n async exportAllData(): Promise<{\n version: number;\n exportedAt: string;\n projects: ProjectData[];\n }> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const projects: ProjectData[] = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n projects.push(data);\n } catch {\n continue;\n }\n }\n\n return {\n version: 1,\n exportedAt: new Date().toISOString(),\n projects,\n };\n }\n\n async importAllData(data: {\n version: number;\n exportedAt: string;\n projects: ProjectData[];\n }): Promise<{\n success: boolean;\n imported: number;\n errors: number;\n errorDetails: string[];\n }> {\n await this.ensureDirectory();\n\n let imported = 0;\n let errors = 0;\n const errorDetails: string[] = [];\n\n if (!data.projects || !Array.isArray(data.projects)) {\n throw new Error('Invalid backup data: projects array is required');\n }\n\n for (const projectData of data.projects) {\n try {\n if (!projectData.project || !projectData.project.id) {\n errors++;\n errorDetails.push('Skipping invalid project: missing project or id');\n continue;\n }\n\n const filePath = this.getFilePath(projectData.project.id);\n await writeJsonFile(filePath, projectData);\n imported++;\n } catch (error) {\n errors++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n errorDetails.push(`Failed to import project ${projectData.project?.id || 'unknown'}: ${errorMessage}`);\n }\n }\n\n return {\n success: errors === 0,\n imported,\n errors,\n errorDetails,\n };\n }\n}\n\nexport const storage = new ProjectStorage();\n","import * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Get the storage directory for roadmap-skill projects\n * Returns: ~/.roadmap-skill/projects\n */\nexport function getStorageDir(): string {\n const homeDir = os.homedir();\n return path.join(homeDir, '.roadmap-skill', 'projects');\n}\n","import { z } from 'zod';\nimport { TaskService } from '../services/index.js';\nimport { storage } from '../storage/index.js';\nimport type { Task, TaskSummary } from '../models/index.js';\n\nconst TaskStatusEnum = z.enum(['todo', 'in-progress', 'review', 'done']);\nconst TaskPriorityEnum = z.enum(['low', 'medium', 'high', 'critical']);\n\nfunction toTaskSummary(task: Task): TaskSummary {\n return {\n id: task.id,\n title: task.title,\n status: task.status,\n priority: task.priority,\n dueDate: task.dueDate,\n assignee: task.assignee,\n tags: task.tags,\n };\n}\nexport const createTaskTool = {\n name: 'create_task',\n description: 'Create a new task in a project. tags must be existing tag IDs from the same project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n title: z.string().min(1, 'Task title is required'),\n description: z.string(),\n priority: TaskPriorityEnum.default('medium'),\n tags: z.array(z.string()).default([]),\n dueDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n assignee: z.string().optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n tags: string[];\n dueDate?: string;\n assignee?: string;\n verbose?: boolean;\n }) {\n const result = await TaskService.create(input.projectId, {\n title: input.title,\n description: input.description,\n priority: input.priority,\n tags: input.tags,\n dueDate: input.dueDate,\n assignee: input.assignee,\n });\n if (!result.success) return result;\n return {\n success: true,\n data: input.verbose ? result.data : toTaskSummary(result.data),\n };\n },\n};\n\nexport const listTasksTool = {\n name: 'list_tasks',\n description: 'List tasks with optional filters. By default, completed (done) tasks are excluded. Set includeCompleted=true to include them. Returns summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().optional(),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n assignee: z.string().optional(),\n dueBefore: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n dueAfter: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n includeCompleted: z.boolean().optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId?: string;\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n verbose?: boolean;\n }) {\n try {\n const results = await storage.searchTasks({\n projectId: input.projectId,\n status: input.status,\n priority: input.priority,\n tags: input.tags,\n assignee: input.assignee,\n dueBefore: input.dueBefore,\n dueAfter: input.dueAfter,\n includeCompleted: input.includeCompleted,\n });\n const tasks = results.map((r) => r.task);\n return {\n success: true,\n data: input.verbose ? tasks : tasks.map(toTaskSummary),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tasks',\n };\n }\n },\n};\n\nexport const getTaskTool = {\n name: 'get_task',\n description: 'Get a specific task by project ID and task ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n }),\n async execute(input: { projectId: string; taskId: string }) {\n const result = await TaskService.get(input.projectId, input.taskId);\n return result;\n },\n};\n\nexport const updateTaskTool = {\n name: 'update_task',\n description: 'Update an existing task. tags must be existing tag IDs from the same project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n title: z.string().min(1).optional(),\n description: z.string().optional(),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n dueDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional().nullable(),\n assignee: z.string().optional().nullable(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n taskId: string;\n title?: string;\n description?: string;\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n verbose?: boolean;\n }) {\n const { projectId, taskId, verbose, ...updateData } = input;\n const result = await TaskService.update(projectId, taskId, updateData);\n if (!result.success) return result;\n return {\n success: true,\n data: verbose ? result.data : toTaskSummary(result.data),\n };\n },\n};\n\nexport const deleteTaskTool = {\n name: 'delete_task',\n description: 'Delete a task by project ID and task ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n }),\n async execute(input: { projectId: string; taskId: string }) {\n const result = await TaskService.delete(input.projectId, input.taskId);\n\n // 保持向后兼容:将 data: undefined 转换为 { deleted: true }\n if (result.success) {\n return {\n success: true,\n data: { deleted: true },\n };\n }\n\n return result;\n },\n};\n\nexport const batchUpdateTasksTool = {\n name: 'batch_update_tasks',\n description: 'Update multiple tasks at once. tags must be existing tag IDs from the same project. Returns summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskIds: z.array(z.string()).min(1, 'At least one task ID is required'),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n tagOperation: z.enum(['add', 'remove', 'replace']).default('replace'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n taskIds: string[];\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n tagOperation?: 'add' | 'remove' | 'replace';\n verbose?: boolean;\n }) {\n const { projectId, taskIds, tagOperation, verbose, ...restData } = input;\n const result = await TaskService.batchUpdate(projectId, taskIds, {\n ...restData,\n tagOperation,\n });\n if (!result.success) return result;\n return {\n success: true,\n data: {\n updatedTasks: verbose\n ? result.data.updatedTasks\n : result.data.updatedTasks.map(toTaskSummary),\n updatedCount: result.data.updatedCount,\n notFoundIds: result.data.notFoundIds,\n },\n };\n },\n};\n","export { TagService } from './tag-service.js';\nexport { TaskService } from './task-service.js';\nexport * from './types.js';\n","/**\n * Tag Service - Unified business logic for tag management\n * Extracted from tag-tools.ts for better separation of concerns\n */\n\nimport type { ProjectStorage } from '../storage/index.js';\nimport type { Tag, ProjectData } from '../models/index.js';\nimport type {\n ServiceResult,\n CreateTagData,\n UpdateTagData,\n DeleteTagResult,\n TasksByTagResult,\n} from './types.js';\n\n/**\n * Generate a unique tag ID\n * @returns Tag ID in format tag_${timestamp}_${random}\n */\nfunction generateTagId(): string {\n return `tag_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nconst HEX_COLOR_PATTERN = /^#[0-9A-Fa-f]{6}$/;\n\nconst TAG_COLOR_PALETTE = [\n '#FF6B6B',\n '#FF9F43',\n '#FDCB6E',\n '#6C5CE7',\n '#74B9FF',\n '#00B894',\n '#00CEC9',\n '#E17055',\n '#FAB1A0',\n '#55A3FF',\n '#A29BFE',\n '#FD79A8',\n];\n\nfunction hashTagName(value: string): number {\n let hash = 5381;\n for (const char of value.toLowerCase()) {\n hash = (hash * 33) ^ char.charCodeAt(0);\n }\n return Math.abs(hash >>> 0);\n}\n\nfunction resolveTagColor(tagName: string, inputColor?: string): string {\n if (inputColor) {\n return inputColor;\n }\n\n const normalizedTagName = tagName.trim();\n if (normalizedTagName.length === 0) {\n return TAG_COLOR_PALETTE[0];\n }\n\n const colorIndex = hashTagName(normalizedTagName) % TAG_COLOR_PALETTE.length;\n return TAG_COLOR_PALETTE[colorIndex];\n}\n\n/**\n * TagService - Handles all tag-related business logic\n */\nexport class TagService {\n private storage: ProjectStorage;\n\n constructor(storage: ProjectStorage) {\n this.storage = storage;\n }\n\n /**\n * Create a new tag in a project\n * @param projectId - The project ID\n * @param data - Tag creation data\n * @returns The created tag or error\n */\n async create(projectId: string, data: CreateTagData): Promise<ServiceResult<Tag>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check for duplicate tag name (case-insensitive)\n const existingTag = projectData.tags.find(\n (t) => t.name.toLowerCase() === data.name.toLowerCase()\n );\n if (existingTag) {\n return {\n success: false,\n error: `Tag with name '${data.name}' already exists in this project`,\n code: 'DUPLICATE_ERROR',\n };\n }\n\n const resolvedColor = resolveTagColor(data.name, data.color);\n if (!HEX_COLOR_PATTERN.test(resolvedColor)) {\n return {\n success: false,\n error: `Color must be a valid hex code (e.g., #FF5733), received '${resolvedColor}'`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const tag: Tag = {\n id: generateTagId(),\n name: data.name,\n color: resolvedColor,\n description: data.description || '',\n createdAt: now,\n };\n\n projectData.tags.push(tag);\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: tag,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * List all tags in a project\n * @param projectId - The project ID\n * @returns Array of tags or error\n */\n async list(projectId: string): Promise<ServiceResult<Tag[]>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskTagCounts = new Map<string, number>();\n for (const task of projectData.tasks) {\n for (const tagId of task.tags) {\n taskTagCounts.set(tagId, (taskTagCounts.get(tagId) ?? 0) + 1);\n }\n }\n\n return {\n success: true,\n data: projectData.tags.map((tag) => ({\n ...tag,\n taskCount: taskTagCounts.get(tag.id) ?? 0,\n })),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tags',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Update an existing tag\n * @param projectId - The project ID\n * @param tagId - The tag ID\n * @param data - Tag update data\n * @returns The updated tag or error\n */\n async update(\n projectId: string,\n tagId: string,\n data: UpdateTagData\n ): Promise<ServiceResult<Tag>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const tagIndex = projectData.tags.findIndex((t) => t.id === tagId);\n if (tagIndex === -1) {\n return {\n success: false,\n error: `Tag with ID '${tagId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check if there is any field to update\n if (Object.keys(data).length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n code: 'VALIDATION_ERROR',\n };\n }\n\n // Check for duplicate name if updating name (case-insensitive)\n if (data.name) {\n const existingTag = projectData.tags.find(\n (t) =>\n t.name.toLowerCase() === data.name!.toLowerCase() && t.id !== tagId\n );\n if (existingTag) {\n return {\n success: false,\n error: `Tag with name '${data.name}' already exists in this project`,\n code: 'DUPLICATE_ERROR',\n };\n }\n }\n\n if (data.color && !HEX_COLOR_PATTERN.test(data.color)) {\n return {\n success: false,\n error: `Color must be a valid hex code (e.g., #FF5733), received '${data.color}'`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const existingTag = projectData.tags[tagIndex];\n\n const updatedTag: Tag = {\n ...existingTag,\n ...data,\n id: existingTag.id,\n createdAt: existingTag.createdAt,\n };\n\n projectData.tags[tagIndex] = updatedTag;\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: updatedTag,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Delete a tag by ID\n * Also removes the tag from all tasks that use it\n * @param projectId - The project ID\n * @param tagId - The tag ID\n * @returns Delete result with tag info and count of updated tasks\n */\n async delete(projectId: string, tagId: string): Promise<ServiceResult<DeleteTagResult>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const tagIndex = projectData.tags.findIndex((t) => t.id === tagId);\n if (tagIndex === -1) {\n return {\n success: false,\n error: `Tag with ID '${tagId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n const tag = projectData.tags[tagIndex];\n\n // Remove tag from all tasks that use it\n const now = new Date().toISOString();\n let tasksUpdated = 0;\n for (const task of projectData.tasks) {\n const tagIndexInTask = task.tags.indexOf(tagId);\n if (tagIndexInTask !== -1) {\n task.tags.splice(tagIndexInTask, 1);\n task.updatedAt = now;\n tasksUpdated++;\n }\n }\n\n projectData.tags.splice(tagIndex, 1);\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: {\n deleted: true,\n tag,\n tasksUpdated,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Get all tasks that have a specific tag by tag name\n * @param projectId - The project ID\n * @param tagName - The tag name\n * @returns Tag info and matching tasks\n */\n async getTasksByTag(\n projectId: string,\n tagName: string\n ): Promise<ServiceResult<TasksByTagResult>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n // Find tag by name (case-insensitive)\n const tag = projectData.tags.find(\n (t) => t.name.toLowerCase() === tagName.toLowerCase()\n );\n\n if (!tag) {\n return {\n success: false,\n error: `Tag with name '${tagName}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Find all tasks with this tag\n const tasks = projectData.tasks.filter((t) => t.tags.includes(tag.id));\n\n return {\n success: true,\n data: {\n tag,\n tasks,\n count: tasks.length,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get tasks by tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Helper method to save project data\n * @param projectId - The project ID\n * @param projectData - The project data to save\n */\n private async saveProjectData(projectId: string, projectData: ProjectData): Promise<void> {\n const filePath = this.storage.getFilePath(projectId);\n const { writeJsonFile } = await import('../utils/file-helpers.js');\n await writeJsonFile(filePath, projectData);\n }\n}\n","/**\n * Task Service - Unified business logic for task operations\n * Extracted from task-tools.ts to enable reuse across different interfaces\n */\n\nimport type { ProjectData, Task, TaskStatus } from '../models/index.js';\nimport { storage } from '../storage/index.js';\nimport { writeJsonFile } from '../utils/file-helpers.js';\nimport type {\n ServiceResult,\n CreateTaskData,\n UpdateTaskData,\n BatchUpdateTaskData,\n BatchUpdateResult,\n} from './types.js';\n\n/**\n * Generate a unique task ID\n * Format: task_${timestamp}_${random}\n */\nfunction generateTaskId(): string {\n return `task_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Calculate completedAt based on status change\n * - When status changes to 'done', set completedAt to current time\n * - When status changes from 'done' to other, clear completedAt\n * - Otherwise, preserve existing completedAt\n */\nfunction calculateCompletedAt(\n currentStatus: TaskStatus,\n newStatus: TaskStatus | undefined,\n existingCompletedAt: string | null,\n now: string\n): string | null {\n // Status is not being updated\n if (!newStatus) {\n return existingCompletedAt;\n }\n\n // Status changing to 'done'\n if (newStatus === 'done' && currentStatus !== 'done') {\n return now;\n }\n\n // Status changing from 'done' to something else\n if (currentStatus === 'done' && newStatus !== 'done') {\n return null;\n }\n\n // Status changing but not involving 'done' transition\n return existingCompletedAt;\n}\n\nfunction findInvalidTagIds(projectData: ProjectData, tagIds: string[]): string[] {\n const validTagIds = new Set(projectData.tags.map((tag) => tag.id));\n return tagIds.filter((tagId) => !validTagIds.has(tagId));\n}\n\n/**\n * TaskService - Business logic for task operations\n */\nexport const TaskService = {\n /**\n * Create a new task in a project\n * @param projectId - The project ID\n * @param data - Task creation data\n * @returns The created task or error\n */\n async create(projectId: string, data: CreateTaskData): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const incomingTagIds = data.tags ?? [];\n const invalidTagIds = findInvalidTagIds(projectData, incomingTagIds);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const task: Task = {\n id: generateTaskId(),\n projectId,\n title: data.title,\n description: data.description,\n status: 'todo',\n priority: data.priority ?? 'medium',\n tags: incomingTagIds,\n dueDate: data.dueDate ?? null,\n assignee: data.assignee ?? null,\n createdAt: now,\n updatedAt: now,\n completedAt: null,\n };\n\n projectData.tasks.push(task);\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: task,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Get a specific task by project ID and task ID\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @returns The task or error\n */\n async get(projectId: string, taskId: string): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const task = projectData.tasks.find((t) => t.id === taskId);\n if (!task) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n return {\n success: true,\n data: task,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Update an existing task\n * Handles completedAt automatically based on status changes\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @param data - Task update data\n * @returns The updated task or error\n */\n async update(\n projectId: string,\n taskId: string,\n data: UpdateTaskData\n ): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check if there's anything to update\n const updateKeys = Object.keys(data);\n if (updateKeys.length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n code: 'VALIDATION_ERROR',\n };\n }\n\n if (data.tags) {\n const invalidTagIds = findInvalidTagIds(projectData, data.tags);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n }\n\n const now = new Date().toISOString();\n const existingTask = projectData.tasks[taskIndex];\n\n // Calculate completedAt based on status change\n const completedAt = calculateCompletedAt(\n existingTask.status,\n data.status,\n existingTask.completedAt,\n now\n );\n\n const updatedTask: Task = {\n ...existingTask,\n ...data,\n id: existingTask.id,\n projectId: existingTask.projectId,\n createdAt: existingTask.createdAt,\n updatedAt: now,\n completedAt,\n };\n\n projectData.tasks[taskIndex] = updatedTask;\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: updatedTask,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Delete a task by project ID and task ID\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @returns Void or error\n */\n async delete(projectId: string, taskId: string): Promise<ServiceResult<void>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n const now = new Date().toISOString();\n projectData.tasks.splice(taskIndex, 1);\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: undefined,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * List tasks with optional filters\n * @param filters - Optional filters for the search\n * @returns Array of tasks or error\n */\n async list(filters?: {\n projectId?: string;\n status?: TaskStatus;\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n }): Promise<ServiceResult<Task[]>> {\n try {\n const results = await storage.searchTasks({\n projectId: filters?.projectId,\n status: filters?.status,\n priority: filters?.priority,\n tags: filters?.tags,\n assignee: filters?.assignee,\n dueBefore: filters?.dueBefore,\n dueAfter: filters?.dueAfter,\n includeCompleted: filters?.includeCompleted,\n });\n\n // Extract just the tasks from the results\n const tasks = results.map((r) => r.task);\n\n return {\n success: true,\n data: tasks,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tasks',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Update multiple tasks at once\n * @param projectId - The project ID\n * @param taskIds - Array of task IDs to update\n * @param data - Batch update data\n * @returns Batch update result or error\n */\n async batchUpdate(\n projectId: string,\n taskIds: string[],\n data: BatchUpdateTaskData\n ): Promise<ServiceResult<BatchUpdateResult>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const now = new Date().toISOString();\n const updatedTasks: Task[] = [];\n const notFoundIds: string[] = [];\n\n for (const taskId of taskIds) {\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n notFoundIds.push(taskId);\n continue;\n }\n\n const existingTask = projectData.tasks[taskIndex];\n let updatedTags = existingTask.tags ?? [];\n\n if (data.tags) {\n const invalidTagIds = findInvalidTagIds(projectData, data.tags);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n }\n\n // Handle tags based on tagOperation\n if (data.tags) {\n const existingTags = existingTask.tags ?? [];\n switch (data.tagOperation) {\n case 'add':\n updatedTags = [...new Set([...existingTags, ...data.tags])];\n break;\n case 'remove':\n updatedTags = existingTags.filter((tag) => !data.tags!.includes(tag));\n break;\n case 'replace':\n default:\n updatedTags = data.tags;\n break;\n }\n }\n\n // Calculate completedAt based on status change\n const completedAt = calculateCompletedAt(\n existingTask.status,\n data.status,\n existingTask.completedAt,\n now\n );\n\n const updatedTask: Task = {\n ...existingTask,\n ...(data.status && { status: data.status }),\n ...(data.priority && { priority: data.priority }),\n tags: updatedTags,\n updatedAt: now,\n completedAt,\n };\n\n projectData.tasks[taskIndex] = updatedTask;\n updatedTasks.push(updatedTask);\n }\n\n if (updatedTasks.length === 0) {\n return {\n success: false,\n error: 'No tasks were found to update',\n code: 'NOT_FOUND',\n };\n }\n\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: {\n updatedTasks,\n updatedCount: updatedTasks.length,\n notFoundIds: notFoundIds.length > 0 ? notFoundIds : undefined,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to batch update tasks',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n};\n","/**\n * Service layer type definitions\n * Provides unified result types and service interfaces\n */\n\nimport type { ProjectStorage } from '../storage/index.js';\nimport type { Task, Tag, TaskStatus, TaskPriority } from '../models/index.js';\n\n// ============================================================================\n// Result Types\n// ============================================================================\n\n/**\n * Error codes for service operations\n */\nexport type ErrorCode =\n | 'NOT_FOUND'\n | 'VALIDATION_ERROR'\n | 'DUPLICATE_ERROR'\n | 'UNAUTHORIZED'\n | 'INTERNAL_ERROR';\n\n/**\n * Service result type - discriminated union for success/failure\n */\nexport type ServiceResult<T> =\n | { success: true; data: T }\n | { success: false; error: string; code: ErrorCode };\n\n// ============================================================================\n// Task Service Types\n// ============================================================================\n\nexport interface CreateTaskData {\n title: string;\n description: string;\n priority?: TaskPriority;\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n}\n\nexport interface UpdateTaskData {\n title?: string;\n description?: string;\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n}\n\nexport interface BatchUpdateTaskData {\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n tagOperation?: 'add' | 'remove' | 'replace';\n}\n\nexport interface BatchUpdateResult {\n updatedTasks: Task[];\n updatedCount: number;\n notFoundIds?: string[];\n}\n\n// ============================================================================\n// Tag Service Types\n// ============================================================================\n\nexport interface CreateTagData {\n name: string;\n color?: string;\n description?: string;\n}\n\nexport interface UpdateTagData {\n name?: string;\n color?: string;\n description?: string;\n}\n\nexport interface DeleteTagResult {\n deleted: true;\n tag: Tag;\n tasksUpdated: number;\n}\n\nexport interface TasksByTagResult {\n tag: Tag;\n tasks: Task[];\n count: number;\n}\n\n// ============================================================================\n// Service Context\n// ============================================================================\n\n/**\n * Service context for dependency injection\n */\nexport interface ServiceContext {\n storage: ProjectStorage;\n}\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\n/**\n * Task Service interface\n */\nexport interface ITaskService {\n create(projectId: string, data: CreateTaskData): Promise<ServiceResult<Task>>;\n get(projectId: string, taskId: string): Promise<ServiceResult<Task>>;\n update(projectId: string, taskId: string, data: UpdateTaskData): Promise<ServiceResult<Task>>;\n delete(projectId: string, taskId: string): Promise<ServiceResult<void>>;\n list(filters?: {\n projectId?: string;\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n }): Promise<ServiceResult<Task[]>>;\n batchUpdate(\n projectId: string,\n taskIds: string[],\n data: BatchUpdateTaskData\n ): Promise<ServiceResult<BatchUpdateResult>>;\n}\n\n/**\n * Tag Service interface\n */\nexport interface ITagService {\n create(projectId: string, data: CreateTagData): Promise<ServiceResult<Tag>>;\n list(projectId: string): Promise<ServiceResult<Tag[]>>;\n update(projectId: string, tagId: string, data: UpdateTagData): Promise<ServiceResult<Tag>>;\n delete(projectId: string, tagId: string): Promise<ServiceResult<DeleteTagResult>>;\n getTasksByTag(projectId: string, tagName: string): Promise<ServiceResult<TasksByTagResult>>;\n}\n","import { z } from 'zod';\nimport { TagService } from '../services/index.js';\nimport { storage } from '../storage/index.js';\n\nconst tagService = new TagService(storage);\n\nexport const createTagTool = {\n name: 'create_tag',\n description: 'Create a new tag in a project. If color is omitted, it is generated deterministically from tag name.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n name: z.string().min(1, 'Tag name is required'),\n color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Color must be a valid hex code (e.g., #FF5733)').optional(),\n description: z.string().default(''),\n }),\n async execute(input: {\n projectId: string;\n name: string;\n color?: string;\n description: string;\n }) {\n const { projectId, ...data } = input;\n const result = await tagService.create(projectId, data);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const listTagsTool = {\n name: 'list_tags',\n description: 'List all tags in a project',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n }),\n async execute(input: { projectId: string }) {\n const result = await tagService.list(input.projectId);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const updateTagTool = {\n name: 'update_tag',\n description: 'Update an existing tag',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagId: z.string().min(1, 'Tag ID is required'),\n name: z.string().min(1).optional(),\n color: z.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),\n description: z.string().optional(),\n }),\n async execute(input: {\n projectId: string;\n tagId: string;\n name?: string;\n color?: string;\n description?: string;\n }) {\n const { projectId, tagId, ...data } = input;\n const result = await tagService.update(projectId, tagId, data);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const deleteTagTool = {\n name: 'delete_tag',\n description: 'Delete a tag by project ID and tag ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagId: z.string().min(1, 'Tag ID is required'),\n }),\n async execute(input: { projectId: string; tagId: string }) {\n const result = await tagService.delete(input.projectId, input.tagId);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const getTasksByTagTool = {\n name: 'get_tasks_by_tag',\n description: 'Get all tasks that have a specific tag',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagName: z.string().min(1, 'Tag name is required'),\n }),\n async execute(input: { projectId: string; tagName: string }) {\n const result = await tagService.getTasksByTag(input.projectId, input.tagName);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n","import { createServer } from '../web/server.js';\nimport open from 'open';\nimport type { Server } from 'http';\n\nlet activeServer: Server | null = null;\nlet activePort: number | null = null;\n\nfunction getServerPort(server: Server): number | null {\n const address = server.address();\n\n if (address && typeof address === 'object' && 'port' in address) {\n return typeof address.port === 'number' ? address.port : null;\n }\n\n return null;\n}\n\nasync function closeServer(server: Server): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n\n const forceCloseServer = server as {\n closeAllConnections?: () => void;\n closeIdleConnections?: () => void;\n };\n forceCloseServer.closeIdleConnections?.();\n forceCloseServer.closeAllConnections?.();\n });\n}\n\nasync function openBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch (error) {\n console.error('Failed to open browser:', error);\n }\n}\n\nexport const openWebInterfaceTool = {\n name: 'open_web_interface',\n description: 'Open web visualization interface',\n parameters: {\n type: 'object',\n properties: {\n port: {\n type: 'number',\n description: 'Port to run the web interface on (default: 7860)',\n },\n },\n },\n async execute(args: { port?: number }) {\n const requestedPort = args.port || 7860;\n\n if (activeServer) {\n const runningPort = getServerPort(activeServer) ?? activePort;\n\n if (runningPort !== requestedPort) {\n throw new Error(`Web interface is already running on port ${runningPort ?? 'unknown'}. Please close it before opening a different port.`);\n }\n\n const url = `http://localhost:${runningPort ?? requestedPort}`;\n await openBrowser(url);\n\n return { \n message: 'Web interface is already running',\n url,\n };\n }\n\n const url = `http://localhost:${requestedPort}`;\n\n try {\n activeServer = await createServer(requestedPort);\n activePort = requestedPort;\n await openBrowser(url);\n\n return {\n message: 'Web interface started successfully and opened in browser',\n url,\n };\n } catch (error) {\n activeServer = null;\n activePort = null;\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to start web interface: ${errorMessage}`);\n }\n }\n};\n\nexport const closeWebInterfaceTool = {\n name: 'close_web_interface',\n description: 'Close web visualization interface',\n parameters: {\n type: 'object',\n properties: {},\n },\n async execute() {\n if (!activeServer) {\n return { message: 'Web interface is not running' };\n }\n\n try {\n await closeServer(activeServer);\n activeServer = null;\n activePort = null;\n return { message: 'Web interface stopped' };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to stop web interface: ${errorMessage}`);\n }\n }\n};\n","import express from 'express';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createRequire } from 'node:module';\nimport { existsSync } from 'node:fs';\nimport type { Server } from 'http';\nimport { storage } from '../storage/index.js';\nimport { TaskService, TagService } from '../services/index.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Resolve the path to the web app static files using multiple fallback strategies.\n * Handles npx execution, global installation, local development, and bundled execution.\n */\nfunction resolveAppPath(): string {\n const candidates: Array<{ path: string; source: string }> = [];\n\n try {\n const require = createRequire(import.meta.url);\n const pkgRoot = path.dirname(require.resolve('../../package.json'));\n candidates.push({ path: path.join(pkgRoot, 'dist/web/app'), source: 'package.json resolve' });\n } catch {\n // Package.json not resolvable\n }\n\n // Primary path when bundled: __dirname = dist/, so dist/web/app is correct\n candidates.push({ path: path.join(__dirname, 'web/app'), source: '__dirname/web/app' });\n candidates.push({ path: path.join(__dirname, 'app'), source: '__dirname relative' });\n candidates.push({ path: path.join(process.cwd(), 'dist/web/app'), source: 'process.cwd()' });\n candidates.push({ path: path.join(__dirname, '../web/app'), source: '__dirname/../web/app' });\n\n for (const { path: candidatePath, source } of candidates) {\n const indexPath = path.join(candidatePath, 'index.html');\n if (existsSync(indexPath)) {\n console.error(`[roadmap-skill] Static files found at: ${candidatePath} (via ${source})`);\n return candidatePath;\n }\n }\n\n const triedPaths = candidates.map(c => ` - ${c.path} (${c.source})`).join('\\n');\n throw new Error(\n `Cannot find web app static files.\\n\\n` +\n `Tried:\\n${triedPaths}\\n\\n` +\n `Ensure the package is installed correctly and web assets exist.`\n );\n}\n\nconst tagService = new TagService(storage);\n\nexport function createServer(port: number = 7860): Promise<Server> {\n return new Promise((resolve, reject) => {\n const app = express();\n\n app.use(express.json());\n\n app.get('/api/projects', async (_req, res) => {\n try {\n const projects = await storage.listProjects();\n res.json(projects);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/projects/:id', async (req, res) => {\n try {\n const project = await storage.readProject(req.params.id);\n if (!project) {\n res.status(404).json({ error: 'Project not found' });\n return;\n }\n res.json(project);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/tasks', async (req, res) => {\n try {\n const filters: Record<string, unknown> = { ...req.query };\n\n // Convert includeCompleted from string to boolean\n if (filters.includeCompleted !== undefined) {\n filters.includeCompleted = filters.includeCompleted === 'true';\n }\n\n const tasks = await storage.searchTasks(filters as any);\n res.json(tasks);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/projects', async (req, res) => {\n try {\n const project = await storage.createProject(req.body);\n res.json({ success: true, data: project });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/projects', async (req, res) => {\n try {\n const { projectId, ...updateData } = req.body;\n const project = await storage.updateProject(projectId, updateData);\n res.json({ success: true, data: project });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/projects', async (req, res) => {\n try {\n const { projectId } = req.query;\n await storage.deleteProject(projectId as string);\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/tasks', async (req, res) => {\n try {\n const { projectId, ...taskData } = req.body;\n const result = await TaskService.create(projectId, taskData);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/tasks', async (req, res) => {\n try {\n const { projectId, taskId, ...updateData } = req.body;\n const result = await TaskService.update(projectId, taskId, updateData);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/tasks', async (req, res) => {\n try {\n const { projectId, taskId } = req.query;\n const result = await TaskService.delete(projectId as string, taskId as string);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/projects/:projectId/tags', async (req, res) => {\n try {\n const { projectId } = req.params;\n const result = await tagService.create(projectId, req.body);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/projects/:projectId/tags', async (req, res) => {\n try {\n const { projectId } = req.params;\n const result = await tagService.list(projectId);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/projects/:projectId/tags/:tagId', async (req, res) => {\n try {\n const { projectId, tagId } = req.params;\n const result = await tagService.update(projectId, tagId, req.body);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/projects/:projectId/tags/:tagId', async (req, res) => {\n try {\n const { projectId, tagId } = req.params;\n const result = await tagService.delete(projectId, tagId);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/backup', async (_req, res) => {\n try {\n const backup = await storage.exportAllData();\n const filename = `roadmap-skill-backup-${new Date().toISOString().split('T')[0]}.json`;\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Content-Disposition', `attachment; filename=\"${filename}\"`);\n res.json(backup);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/backup', async (req, res) => {\n try {\n const result = await storage.importAllData(req.body);\n res.json(result);\n } catch (error) {\n res.status(400).json({\n success: false,\n error: (error as Error).message,\n });\n }\n });\n\n const distPath = resolveAppPath();\n app.use(express.static(distPath));\n\n app.get('*', (req, res) => {\n if (req.path.startsWith('/api')) {\n res.status(404).json({ error: 'API not found' });\n return;\n }\n res.sendFile(path.join(distPath, 'index.html'));\n });\n\n const server = app.listen(port, '127.0.0.1');\n\n server.once('listening', () => {\n console.error(`Web interface server running at http://localhost:${port}`);\n resolve(server);\n });\n\n server.once('error', (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use`));\n return;\n }\n\n reject(error);\n });\n });\n}\n\n// Start server if run directly\nif (process.argv[1]?.endsWith('server.js')) {\n const port = parseInt(process.argv[2] || '7860', 10);\n createServer(port).catch(err => {\n console.error('Failed to start server:', err);\n process.exit(1);\n });\n}\n","import { z } from 'zod';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { storage } from '../storage/index.js';\nimport type { CreateProjectInput, Tag, Task } from '../models/index.js';\n\nconst TEMPLATES_DIR = path.join(process.cwd(), 'templates');\n\ninterface TemplateMetadata {\n name: string;\n description: string;\n projectType: string;\n tasks: Array<{\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n tags: string[];\n estimatedHours?: number;\n }>;\n tags: Array<{\n name: string;\n color: string;\n }>;\n}\n\nasync function getTemplateFiles(): Promise<string[]> {\n try {\n const files = await fs.readdir(TEMPLATES_DIR);\n return files.filter((f) => f.endsWith('.json'));\n } catch {\n return [];\n }\n}\n\nasync function loadTemplate(templateName: string): Promise<TemplateMetadata | null> {\n try {\n const fileName = templateName.endsWith('.json') ? templateName : `${templateName}.json`;\n const filePath = path.join(TEMPLATES_DIR, fileName);\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as TemplateMetadata;\n } catch {\n return null;\n }\n}\n\nfunction generateId(prefix: string): string {\n return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport const listTemplatesTool = {\n name: 'list_templates',\n description: 'List all available project templates',\n inputSchema: z.object({}),\n async execute() {\n try {\n const templateFiles = await getTemplateFiles();\n const templates = [];\n\n for (const file of templateFiles) {\n const template = await loadTemplate(file);\n if (template) {\n templates.push({\n name: file.replace('.json', ''),\n displayName: template.name,\n description: template.description,\n projectType: template.projectType,\n taskCount: template.tasks.length,\n tagCount: template.tags.length,\n });\n }\n }\n\n return {\n success: true,\n data: templates,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list templates',\n };\n }\n },\n};\n\nexport const getTemplateTool = {\n name: 'get_template',\n description: 'Get detailed information about a specific template',\n inputSchema: z.object({\n templateName: z.string().min(1, 'Template name is required'),\n }),\n async execute(input: { templateName: string }) {\n try {\n const template = await loadTemplate(input.templateName);\n\n if (!template) {\n return {\n success: false,\n error: `Template '${input.templateName}' not found`,\n };\n }\n\n return {\n success: true,\n data: {\n name: template.name,\n description: template.description,\n projectType: template.projectType,\n tasks: template.tasks.map((t) => ({\n title: t.title,\n description: t.description,\n priority: t.priority,\n tags: t.tags,\n estimatedHours: t.estimatedHours,\n })),\n tags: template.tags,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get template',\n };\n }\n },\n};\n\nexport const applyTemplateTool = {\n name: 'apply_template',\n description: 'Create a new project from a template',\n inputSchema: z.object({\n templateName: z.string().min(1, 'Template name is required'),\n projectName: z.string().min(1, 'Project name is required'),\n description: z.string().default(''),\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format').optional(),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format').optional(),\n }),\n async execute(input: {\n templateName: string;\n projectName: string;\n description: string;\n startDate?: string;\n targetDate?: string;\n }) {\n try {\n const template = await loadTemplate(input.templateName);\n\n if (!template) {\n return {\n success: false,\n error: `Template '${input.templateName}' not found`,\n };\n }\n\n const projectInput: CreateProjectInput = {\n name: input.projectName,\n description: input.description || template.description,\n projectType: template.projectType as 'roadmap' | 'skill-tree' | 'kanban',\n startDate: input.startDate || new Date().toISOString().split('T')[0],\n targetDate: input.targetDate || new Date().toISOString().split('T')[0],\n };\n\n const projectData = await storage.createProject(projectInput);\n const projectId = projectData.project.id;\n const now = new Date().toISOString();\n\n const tagNameToId: Map<string, string> = new Map();\n const tags: Tag[] = [];\n\n for (const templateTag of template.tags) {\n const tag: Tag = {\n id: generateId('tag'),\n name: templateTag.name,\n color: templateTag.color,\n description: '',\n createdAt: now,\n };\n tags.push(tag);\n tagNameToId.set(templateTag.name, tag.id);\n }\n\n const tasks: Task[] = [];\n\n for (const templateTask of template.tasks) {\n const taskTagIds = templateTask.tags\n .map((tagName) => tagNameToId.get(tagName))\n .filter((id): id is string => id !== undefined);\n\n const task: Task = {\n id: generateId('task'),\n projectId,\n title: templateTask.title,\n description: templateTask.description,\n status: 'todo',\n priority: templateTask.priority,\n tags: taskTagIds,\n dueDate: null,\n assignee: null,\n createdAt: now,\n updatedAt: now,\n completedAt: null,\n };\n tasks.push(task);\n }\n\n projectData.tags = tags;\n projectData.tasks = tasks;\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n const { writeJsonFile } = await import('../utils/file-helpers.js');\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: {\n project: projectData.project,\n taskCount: tasks.length,\n tagCount: tags.length,\n tasksCreated: tasks.map((t) => ({\n id: t.id,\n title: t.title,\n priority: t.priority,\n })),\n tagsCreated: tags.map((t) => ({\n id: t.id,\n name: t.name,\n color: t.color,\n })),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to apply template',\n };\n }\n },\n};\n","export {\n projectResources,\n handleResourceRequest,\n getAllResources,\n} from './project-resources.js';\n","import type {\n Resource,\n TextResourceContents,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { storage } from '../storage/index.js';\n\n/**\n * Resource definitions for roadmap projects\n */\nexport const projectResources: Resource[] = [\n {\n uri: 'roadmap://projects',\n name: 'Project List',\n mimeType: 'application/json',\n description: 'Returns a list of all projects with basic metadata',\n },\n {\n uri: 'roadmap://project/{projectId}',\n name: 'Project Details',\n mimeType: 'application/json',\n description: 'Returns detailed information about a specific project including tasks, milestones, and tags',\n },\n {\n uri: 'roadmap://project/{projectId}/tasks',\n name: 'Project Tasks',\n mimeType: 'application/json',\n description: 'Returns all tasks for a specific project',\n },\n {\n uri: 'roadmap://project/{projectId}/progress',\n name: 'Project Progress',\n mimeType: 'application/json',\n description: 'Returns progress statistics for a specific project',\n },\n];\n\n/**\n * Resource URI patterns for matching\n */\nconst RESOURCE_PATTERNS = {\n projectList: /^roadmap:\\/\\/projects$/,\n projectDetails: /^roadmap:\\/\\/project\\/([^/]+)$/,\n projectTasks: /^roadmap:\\/\\/project\\/([^/]+)\\/tasks$/,\n projectProgress: /^roadmap:\\/\\/project\\/([^/]+)\\/progress$/,\n};\n\n/**\n * Handle resource requests\n * @param uri - The resource URI\n * @returns Resource contents or null if not found\n */\nexport async function handleResourceRequest(\n uri: string\n): Promise<TextResourceContents | null> {\n // Project List: roadmap://projects\n if (RESOURCE_PATTERNS.projectList.test(uri)) {\n return await getProjectListResource(uri);\n }\n\n // Project Details: roadmap://project/{projectId}\n const projectDetailsMatch = uri.match(RESOURCE_PATTERNS.projectDetails);\n if (projectDetailsMatch && !uri.includes('/tasks') && !uri.includes('/progress')) {\n const projectId = projectDetailsMatch[1];\n return await getProjectDetailsResource(uri, projectId);\n }\n\n // Project Tasks: roadmap://project/{projectId}/tasks\n const projectTasksMatch = uri.match(RESOURCE_PATTERNS.projectTasks);\n if (projectTasksMatch) {\n const projectId = projectTasksMatch[1];\n return await getProjectTasksResource(uri, projectId);\n }\n\n // Project Progress: roadmap://project/{projectId}/progress\n const projectProgressMatch = uri.match(RESOURCE_PATTERNS.projectProgress);\n if (projectProgressMatch) {\n const projectId = projectProgressMatch[1];\n return await getProjectProgressResource(uri, projectId);\n }\n\n return null;\n}\n\n/**\n * Get project list resource\n */\nasync function getProjectListResource(uri: string): Promise<TextResourceContents> {\n const projects = await storage.listProjects();\n\n const data = {\n projects: projects.map(p => ({\n id: p.project.id,\n name: p.project.name,\n description: p.project.description,\n status: p.project.status,\n projectType: p.project.projectType,\n taskCount: p.taskCount,\n milestoneCount: p.milestoneCount,\n updatedAt: p.project.updatedAt,\n })),\n totalCount: projects.length,\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project details resource\n */\nasync function getProjectDetailsResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const data = {\n project: projectData.project,\n milestones: projectData.milestones,\n tasks: projectData.tasks,\n tags: projectData.tags,\n stats: {\n taskCount: projectData.tasks.length,\n milestoneCount: projectData.milestones.length,\n tagCount: projectData.tags.length,\n completedTasks: projectData.tasks.filter(t => t.status === 'done').length,\n inProgressTasks: projectData.tasks.filter(t => t.status === 'in-progress').length,\n },\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project tasks resource\n */\nasync function getProjectTasksResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const tasksByStatus = {\n todo: projectData.tasks.filter(t => t.status === 'todo'),\n inProgress: projectData.tasks.filter(t => t.status === 'in-progress'),\n review: projectData.tasks.filter(t => t.status === 'review'),\n done: projectData.tasks.filter(t => t.status === 'done'),\n };\n\n const data = {\n projectId,\n projectName: projectData.project.name,\n tasks: projectData.tasks,\n tasksByStatus,\n summary: {\n total: projectData.tasks.length,\n todo: tasksByStatus.todo.length,\n inProgress: tasksByStatus.inProgress.length,\n review: tasksByStatus.review.length,\n done: tasksByStatus.done.length,\n },\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project progress resource\n */\nasync function getProjectProgressResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const tasks = projectData.tasks;\n const totalTasks = tasks.length;\n const completedTasks = tasks.filter(t => t.status === 'done').length;\n const inProgressTasks = tasks.filter(t => t.status === 'in-progress').length;\n const reviewTasks = tasks.filter(t => t.status === 'review').length;\n const todoTasks = tasks.filter(t => t.status === 'todo').length;\n\n const completionPercentage = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;\n\n const milestones = projectData.milestones;\n const completedMilestones = milestones.filter(m => m.completedAt !== null).length;\n const milestoneProgress = milestones.length > 0 ? Math.round((completedMilestones / milestones.length) * 100) : 0;\n\n // Calculate overdue tasks\n const now = new Date().toISOString();\n const overdueTasks = tasks.filter(t => \n t.dueDate && \n t.dueDate < now && \n t.status !== 'done'\n );\n\n // Priority breakdown\n const priorityBreakdown = {\n critical: tasks.filter(t => t.priority === 'critical').length,\n high: tasks.filter(t => t.priority === 'high').length,\n medium: tasks.filter(t => t.priority === 'medium').length,\n low: tasks.filter(t => t.priority === 'low').length,\n };\n\n const data = {\n projectId,\n projectName: projectData.project.name,\n projectStatus: projectData.project.status,\n dates: {\n startDate: projectData.project.startDate,\n targetDate: projectData.project.targetDate,\n daysRemaining: calculateDaysRemaining(projectData.project.targetDate),\n },\n taskProgress: {\n total: totalTasks,\n completed: completedTasks,\n inProgress: inProgressTasks,\n review: reviewTasks,\n todo: todoTasks,\n completionPercentage,\n },\n milestoneProgress: {\n total: milestones.length,\n completed: completedMilestones,\n percentage: milestoneProgress,\n },\n overdueTasks: {\n count: overdueTasks.length,\n tasks: overdueTasks.map(t => ({\n id: t.id,\n title: t.title,\n dueDate: t.dueDate,\n status: t.status,\n })),\n },\n priorityBreakdown,\n lastUpdated: projectData.project.updatedAt,\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Calculate days remaining until target date\n */\nfunction calculateDaysRemaining(targetDate: string): number | null {\n const target = new Date(targetDate);\n const now = new Date();\n const diffTime = target.getTime() - now.getTime();\n const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n return diffDays > 0 ? diffDays : null;\n}\n\n/**\n * Get all available resources\n */\nexport function getAllResources(): Resource[] {\n return projectResources;\n}\n","export {\n projectPrompts,\n getRecommendNextTasksPrompt,\n getAutoPrioritizePrompt,\n getEnhanceTaskDetailsPrompt,\n getQuickCapturePrompt,\n getPromptByName,\n getAllPrompts,\n} from './project-prompts.js';\n","import type {\n Prompt,\n GetPromptResult,\n} from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Curated Prompts - Help Agents use Roadmap Skill more intelligently\n */\nexport const projectPrompts: Prompt[] = [\n {\n name: 'suggest-tasks',\n description: 'Intelligently recommend the next priority tasks based on urgency, due dates, and project status',\n arguments: [\n {\n name: 'projectId',\n description: 'Specific project ID (optional; if not provided, auto-detect from current context or analyze all projects)',\n required: false,\n },\n {\n name: 'limit',\n description: 'Number of tasks to recommend (default: 3)',\n required: false,\n },\n ],\n },\n {\n name: 'auto-prioritize',\n description: 'Automatically analyze tasks and intelligently adjust priorities, considering due dates, dependencies, and project importance',\n arguments: [\n {\n name: 'projectId',\n description: 'Specific project ID (optional; if not provided, auto-detect from current context or analyze all projects)',\n required: false,\n },\n ],\n },\n {\n name: 'add-task-details',\n description: 'Intelligently enhance task details, including description, acceptance criteria, subtasks, and required resources',\n arguments: [\n {\n name: 'taskId',\n description: 'Task ID to be enhanced',\n required: true,\n },\n ],\n },\n {\n name: 'quick-capture',\n description: 'Quickly capture ideas/tasks, auto-categorize and suggest priorities',\n arguments: [\n {\n name: 'idea',\n description: 'Idea or task description to be captured',\n required: true,\n },\n {\n name: 'projectId',\n description: 'Target project ID (optional; if not provided, auto-detect from current context)',\n required: false,\n },\n ],\n },\n {\n name: 'open-web-ui',\n description: 'Open the web visualization interface for the roadmap skill',\n arguments: [\n {\n name: 'port',\n description: 'Port to run the web interface on (optional, default: 7860)',\n required: false,\n },\n ],\n },\n];\n\n/**\n * Intelligently recommend next tasks\n * Analyze all tasks and recommend optimal execution order based on priority, due dates, and dependencies\n */\nexport function getRecommendNextTasksPrompt(projectId?: string, limit?: string): GetPromptResult {\n const projectHint = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, focus on that project; otherwise, analyze all active projects';\n const taskLimit = limit ? parseInt(limit, 10) : 3;\n\n return {\n description: 'Intelligent Task Recommendation Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `${projectHint}, please recommend the ${taskLimit} tasks I should prioritize next.\n\n## Recommendation Logic (sorted by priority):\n\n### 1. Urgent and Important (Critical priority + Near due date)\n- Critical tasks due today or tomorrow\n- Overdue high-priority tasks\n\n### 2. High-Value Tasks (High priority + Clear due date)\n- High priority tasks due this week\n- Critical path tasks blocking other work\n\n### 3. Quick Wins (Medium priority + Short estimated time)\n- Medium tasks completable in 1-2 hours\n- Tasks that can significantly boost project progress\n\n### 4. Planned Work\n- Tasks marked \"in-progress\" but not yet completed\n- Normal priority tasks due soon\n\n## Please perform the following steps:\n\n1. **List all pending tasks** (status = todo or in-progress)\n2. **Filter high-priority tasks**: critical and high\n3. **Check due dates**: Identify tasks due soon or overdue\n4. **Analyze blocking relationships**: Identify tasks blocking others\n5. **Generate recommendation list**: Provide ${taskLimit} tasks to prioritize with reasons\n\n## Output Format:\n\n### Immediate Action (Critical)\n1. **Task Name** (Project Name)\n - Reason: [Why this task is most urgent]\n - Suggested Action: [What specifically to do]\n\n### Today's Focus (High)\n2. **Task Name** (Project Name)\n - Reason: [Why this task is important]\n - Suggested Action: [What specifically to do]\n\n### Follow-up\n3. **Task Name** (Project Name)\n - Reason: [Why this should be done next]\n - Suggested Action: [What specifically to do]\n\nPlease use the list_tasks tool to fetch task data, then provide intelligent recommendations.\n\n## Important Reminder\nWhen you start working on recommended tasks, please:\n1. Use update_task to set task status to in-progress\n2. After completing the task, use update_task to set status to done\n3. If blocked or have issues, document in description and update status to review\n\nKeep task status synchronized with actual progress!`,\n },\n },\n ],\n };\n}\n\n/**\n * Automatic Priority Optimization\n * Automatically adjust priorities based on due dates, project progress, and task dependencies\n */\nexport function getAutoPrioritizePrompt(projectId?: string): GetPromptResult {\n const projectHint = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, focus on that project; otherwise, analyze all active projects';\n\n return {\n description: 'Intelligent Priority Optimization Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `${projectHint}, please automatically analyze and adjust priorities.\n\n## Priority Adjustment Rules:\n\n### Conditions to Upgrade to Critical:\n- [ ] Due within 48 hours and not completed\n- [ ] Blocking other high/critical tasks\n- [ ] On project critical path and behind schedule\n- [ ] Has external dependencies (e.g., clients, partners) and time is tight\n\n### Conditions to Upgrade to High:\n- [ ] Due within 1 week\n- [ ] Prerequisite for important milestone\n- [ ] Stuck in \"in-progress\" state for too long (over 3 days)\n- [ ] Affects work of multiple team members\n\n### Conditions to Downgrade to Medium/Low:\n- [ ] Due date is far away (>2 weeks) and no dependencies\n- [ ] \"Nice to have\" feature rather than core functionality\n- [ ] Not needed in current phase, can be postponed\n\n### Other Considerations:\n- **Overall project progress**: Tasks for behind-schedule projects should be prioritized higher\n- **Resource availability**: If resources are tight, focus on highest priority\n- **Risk factors**: High-risk tasks should be addressed earlier\n\n## Please perform the following steps:\n\n1. **Get all tasks**: Use list_tasks to fetch task list\n2. **Analyze each task**:\n - Check gap between due date and current date\n - Identify task dependency relationships\n - Evaluate overall project health\n3. **Generate adjustment suggestions**: List tasks needing priority changes with reasons\n4. **Batch update**: Use batch_update_tasks to execute priority adjustments immediately — no confirmation needed\n\n## Output Format:\n\n### Suggested Upgrade to Critical\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | high → critical | Due tomorrow |\n\n### Suggested Upgrade to High\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | medium → high | Blocking follow-up tasks |\n\n### Suggested Downgrade\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | high → medium | Can be postponed |\n\n### Keep Unchanged (Priorities are reasonable)\n- List tasks with reasonable priority settings\n\nPlease provide analysis results and immediately execute batch_update_tasks to apply the priority adjustments — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Intelligent Task Detail Enhancement\n * Auto-complete descriptions, acceptance criteria, etc. based on task title and context\n */\nexport function getEnhanceTaskDetailsPrompt(taskId: string): GetPromptResult {\n return {\n description: 'Task Detail Enhancement Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please help me enhance the details for task ${taskId}.\n\n## Enhancement Content:\n\n### 1. Detailed Description\n- Specific content and background of the task\n- Why this task needs to be done\n- Expected business or technical value\n\n### 2. Acceptance Criteria (Definition of Done)\nList clear completion standards, for example:\n- [ ] Feature implemented and locally tested\n- [ ] Code passes Code Review\n- [ ] Related documentation updated\n- [ ] Unit test coverage > 80%\n\n### 3. Technical/Implementation Details\n- Tech stack or modules involved\n- Files that may need modification\n- Potential challenges or considerations\n\n### 4. Related Resources\n- Related documentation links\n- Reference implementations or example code\n- People to consult\n\n### 5. Subtask Suggestions (if needed)\nIf the task is complex, suggest breaking it down:\n- Subtask 1: ...\n- Subtask 2: ...\n- Subtask 3: ...\n\n## Please perform the following steps:\n\n1. **Get task info**: Use get_task to view current task details\n2. **Get project context**: Use get_project to understand project background\n3. **Analyze task type**:\n - If development task: Add technical details, code locations\n - If design task: Add design specs, review criteria\n - If documentation task: Add doc structure, references\n - If testing task: Add test scenarios, coverage scope\n4. **Apply enhancement**: Use update_task to update task description immediately — no confirmation needed\n\n## Updated task should include:\n\n\\`\\`\\`\n## Background\n[Task background and purpose]\n\n## Acceptance Criteria\n- [ ] [Standard 1]\n- [ ] [Standard 2]\n- [ ] [Standard 3]\n\n## Technical Details\n- Modules: [module name]\n- Key files: [file path]\n- Notes: [important reminders]\n\n## Related Resources\n- Documentation: [link]\n- References: [link]\n\\`\\`\\`\n\nPlease fetch task info and immediately use update_task to apply the enhanced details — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Quick Idea Capture\n * Auto-categorize, suggest priorities, recommend projects\n */\nexport function getQuickCapturePrompt(idea: string, projectId?: string): GetPromptResult {\n const projectContext = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, use that project; otherwise, analyze all active projects and select the best match';\n\n return {\n description: 'Quick Capture Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `I want to quickly capture an idea/task: \"${idea}\"\n\n${projectContext}\n\n## Please complete the following steps immediately:\n\n### 1. Task Information Extraction\nExtract from description:\n- **Task Title**: Concise and clear title (start with verb)\n- **Task Description**: Add context and details\n- **Task Type**: bug / feature / refactor / docs / chore\n- **Estimated Priority**: critical / high / medium / low (based on urgency in description)\n\n### 2. Project Selection (if no project specified)\n- List all active projects\n- Analyze which project the task content is most relevant to\n- Select the most suitable project automatically\n\n### 3. Tag Suggestions\nSuggest relevant tags:\n- Type tags: bug, feature, refactor, docs\n- Priority tags: urgent, important\n- Domain tags: frontend, backend, design, testing (if applicable)\n\nTag consistency rules:\n- list_tags first, then prefer reusing existing tags in that project\n- If no suitable tag exists, create_tag first (color optional, system can auto-generate) and then use the returned tag ID\n- create_task.tags must contain tag IDs only (not tag names)\n\n### 4. Create Task\nUse create_task to create the task immediately — no confirmation needed.\nBefore create_task:\n1. Call list_tags(projectId)\n2. Match suggested tags to existing tags by name (case-insensitive)\n3. For missing tags, call create_tag(projectId, name, color?)\n4. Build create_task.tags from tag IDs only\n\n### 5. Status\nAfter creating, if work starts immediately, use update_task to set status to in-progress.\n\n## Example:\n\n**Input**: \"User reported login page doesn't display correctly on mobile\"\n\n**Output**:\n- Title: Fix login page mobile responsiveness issue\n- Description: User reported the login page displays abnormally on mobile devices, need to check responsive layout.\n- Type: Bug\n- Priority: High (affects user experience)\n- Suggested Tags: bug, frontend, mobile\n- create_task.tags: [existing_or_new_tag_ids]\n- Recommended Project: [Recommend if there's a web project]\n\n## Current Idea:\n\nIdea: \"${idea}\"\n\nAnalyze the idea, select the best matching project, and immediately execute create_task — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Open Web UI\n * Launch the web visualization interface\n */\nexport function getOpenWebUIPrompt(port?: string): GetPromptResult {\n const portNum = port ? parseInt(port, 10) : 7860;\n return {\n description: 'Open Web Visualization Interface',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please open the roadmap-skill web interface by calling the open_web_interface tool with port ${portNum}. Do it immediately without asking for confirmation.`,\n },\n },\n ],\n };\n}\n\n/**\n * Get Prompt by name\n */\nexport function getPromptByName(name: string, args?: Record<string, string>): GetPromptResult | null {\n switch (name) {\n case 'suggest-tasks':\n return getRecommendNextTasksPrompt(args?.projectId, args?.limit);\n case 'auto-prioritize':\n return getAutoPrioritizePrompt(args?.projectId);\n case 'add-task-details':\n return getEnhanceTaskDetailsPrompt(args?.taskId || '');\n case 'quick-capture':\n return getQuickCapturePrompt(args?.idea || '', args?.projectId);\n case 'open-web-ui':\n return getOpenWebUIPrompt(args?.port);\n default:\n return null;\n }\n}\n\n/**\n * Get all available Prompts\n */\nexport function getAllPrompts(): Prompt[] {\n return projectPrompts;\n}\n"],"mappings":"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","names":["path","path","fs","z","storage","existingTag","writeJsonFile","z","toTaskSummary","z","z","path","fileURLToPath","__filename","fileURLToPath","__dirname","require","tagService","url","z","path","fs","z","writeJsonFile","createServer"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/file-helpers.ts","../src/index.ts","../src/server.ts","../src/tools/index.ts","../src/tools/project-tools.ts","../src/storage/index.ts","../src/utils/path-helpers.ts","../src/tools/task-tools.ts","../src/services/index.ts","../src/services/tag-service.ts","../src/services/task-service.ts","../src/services/types.ts","../src/tools/tag-tools.ts","../src/tools/web-tools.ts","../src/web/server.ts","../src/tools/template-tools.ts","../src/resources/index.ts","../src/resources/project-resources.ts","../src/prompts/index.ts","../src/prompts/project-prompts.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import * as fs from 'fs/promises';\n\n/**\n * Read and parse a JSON file\n * @param filePath - Path to the JSON file\n * @returns Parsed JSON data\n * @throws Error if file cannot be read or parsed\n */\nexport async function readJsonFile<T>(filePath: string): Promise<T> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to read JSON file ${filePath}: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Write data to a JSON file\n * @param filePath - Path to the JSON file\n * @param data - Data to serialize and write\n * @throws Error if file cannot be written\n */\nexport async function writeJsonFile<T>(filePath: string, data: T): Promise<void> {\n try {\n const content = JSON.stringify(data, null, 2);\n await fs.writeFile(filePath, content, 'utf-8');\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to write JSON file ${filePath}: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Ensure a directory exists, creating it recursively if needed\n * @param dirPath - Path to the directory\n * @throws Error if directory cannot be created\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to create directory ${dirPath}: ${error.message}`);\n }\n throw error;\n }\n}\n","import { startServer } from './server.js';\n\nasync function main() {\n process.on('SIGINT', () => {\n console.error('Received SIGINT, shutting down gracefully...');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n console.error('Received SIGTERM, shutting down gracefully...');\n process.exit(0);\n });\n\n process.on('uncaughtException', (error) => {\n console.error('Uncaught exception:', error);\n // Do not exit — keep MCP stdio transport alive\n });\n\n process.on('unhandledRejection', (reason) => {\n console.error('Unhandled rejection:', reason);\n // Do not exit — keep MCP stdio transport alive\n });\n\n try {\n await startServer();\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\nmain();\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n\tCallToolRequestSchema,\n\tListToolsRequestSchema,\n\tListResourcesRequestSchema,\n\tReadResourceRequestSchema,\n\tListPromptsRequestSchema,\n\tGetPromptRequestSchema,\n\ttype CallToolRequest,\n\ttype ListToolsRequest,\n\ttype ListResourcesRequest,\n\ttype ReadResourceRequest,\n\ttype ListPromptsRequest,\n\ttype GetPromptRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nimport {\n\tcreateProjectTool,\n\tlistProjectsTool,\n\tgetProjectTool,\n\tupdateProjectTool,\n\tdeleteProjectTool,\n\tcreateTaskTool,\n\tlistTasksTool,\n\tgetTaskTool,\n\tupdateTaskTool,\n\tdeleteTaskTool,\n\tbatchUpdateTasksTool,\n\tcreateTagTool,\n\tlistTagsTool,\n\tupdateTagTool,\n\tdeleteTagTool,\n\tgetTasksByTagTool,\n\topenWebInterfaceTool,\n\tcloseWebInterfaceTool,\n} from \"./tools/index.js\";\nimport { getAllResources, handleResourceRequest } from \"./resources/index.js\";\nimport { getAllPrompts, getPromptByName } from \"./prompts/index.js\";\n\nconst allTools = [\n\tcreateProjectTool,\n\tlistProjectsTool,\n\tgetProjectTool,\n\tupdateProjectTool,\n\tdeleteProjectTool,\n\tcreateTaskTool,\n\tlistTasksTool,\n\tgetTaskTool,\n\tupdateTaskTool,\n\tdeleteTaskTool,\n\tbatchUpdateTasksTool,\n\tcreateTagTool,\n\tlistTagsTool,\n\tupdateTagTool,\n\tdeleteTagTool,\n\tgetTasksByTagTool,\n\topenWebInterfaceTool,\n\tcloseWebInterfaceTool,\n];\n\nconst toolMap = new Map(allTools.map((tool) => [tool.name, tool]));\n\nexport function createServer(): Server {\n\tconst server = new Server(\n\t\t{\n\t\t\tname: \"roadmap-skill\",\n\t\t\tversion: \"0.2.1\",\n\t\t},\n\t\t{\n\t\t\tcapabilities: {\n\t\t\t\ttools: {},\n\t\t\t\tresources: {},\n\t\t\t\tprompts: {},\n\t\t\t},\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListToolsRequestSchema,\n\t\tasync (_request: ListToolsRequest) => {\n\t\t\treturn {\n\t\t\t\ttools: allTools.map((tool) => {\n\t\t\t\t\tconst rawSchema =\n\t\t\t\t\t\t(tool as any).parameters || (tool as any).inputSchema;\n\t\t\t\t\tlet inputSchema: Record<string, unknown>;\n\n\t\t\t\t\tif (!rawSchema) {\n\t\t\t\t\t\tinputSchema = { type: \"object\" };\n\t\t\t\t\t} else if (rawSchema.type === \"object\") {\n\t\t\t\t\t\tinputSchema = rawSchema;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinputSchema = zodToJsonSchema(rawSchema, {\n\t\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t\t$refStrategy: \"none\",\n\t\t\t\t\t\t}).definitions?.[tool.name] || { type: \"object\" };\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tinputSchema,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tCallToolRequestSchema,\n\t\tasync (request: CallToolRequest) => {\n\t\t\tconst { name, arguments: args } = request.params;\n\t\t\tconst tool = toolMap.get(name);\n\n\t\t\tif (!tool) {\n\t\t\t\tthrow new Error(`Unknown tool: ${name}`);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await tool.execute(args as never);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: JSON.stringify(result, null, 2),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n } catch (error) {\n\t\t\t\tconst errorMessage =\n\t\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `Tool execution failed: ${errorMessage}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListResourcesRequestSchema,\n\t\tasync (_request: ListResourcesRequest) => {\n\t\t\tconst resources = getAllResources();\n\t\t\treturn { resources };\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tReadResourceRequestSchema,\n\t\tasync (request: ReadResourceRequest) => {\n\t\t\tconst uri = request.params.uri;\n\t\t\tconst resourceContent = await handleResourceRequest(uri);\n\n\t\t\tif (!resourceContent) {\n\t\t\t\tthrow new Error(`Resource not found: ${uri}`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontents: [resourceContent],\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tListPromptsRequestSchema,\n\t\tasync (_request: ListPromptsRequest) => {\n\t\t\tconst prompts = getAllPrompts();\n\t\t\treturn { prompts };\n\t\t},\n\t);\n\n\tserver.setRequestHandler(\n\t\tGetPromptRequestSchema,\n\t\tasync (request: GetPromptRequest) => {\n\t\t\tconst { name, arguments: args } = request.params;\n\t\t\tconst promptResult = getPromptByName(\n\t\t\t\tname,\n\t\t\t\targs as Record<string, string> | undefined,\n\t\t\t);\n\n\t\t\tif (!promptResult) {\n\t\t\t\tthrow new Error(`Prompt not found: ${name}`);\n\t\t\t}\n\n\t\t\treturn promptResult;\n\t\t},\n\t);\n\n\treturn server;\n}\n\nexport async function startServer(): Promise<void> {\n\tconst server = createServer();\n\tconst transport = new StdioServerTransport();\n\n\tconsole.error(\"Roadmap Skill MCP Server starting...\");\n\n\ttry {\n\t\tawait server.connect(transport);\n\t\tconsole.error(\"Roadmap Skill MCP Server connected and ready\");\n\t} catch (error) {\n\t\tconsole.error(\"Failed to start server:\", error);\n\t\tthrow error;\n\t}\n}\n","export {\n createProjectTool,\n listProjectsTool,\n getProjectTool,\n updateProjectTool,\n deleteProjectTool,\n} from './project-tools.js';\n\nexport {\n createTaskTool,\n listTasksTool,\n getTaskTool,\n updateTaskTool,\n deleteTaskTool,\n batchUpdateTasksTool,\n} from './task-tools.js';\n\nexport {\n createTagTool,\n listTagsTool,\n updateTagTool,\n deleteTagTool,\n getTasksByTagTool,\n} from './tag-tools.js';\n\nexport {\n openWebInterfaceTool,\n closeWebInterfaceTool,\n} from './web-tools.js';\n\nexport {\n listTemplatesTool,\n getTemplateTool,\n applyTemplateTool,\n} from './template-tools.js';\n","import { z } from 'zod';\nimport { storage } from '../storage/index.js';\nimport type { Project, ProjectSummary, Task, TaskSummary, CreateProjectInput, UpdateProjectInput } from '../models/index.js';\n\nconst ProjectTypeEnum = z.enum(['roadmap', 'skill-tree', 'kanban']);\nconst ProjectStatusEnum = z.enum(['active', 'completed', 'archived']);\n\nfunction toProjectSummary(\n project: Project,\n taskCount: number,\n tags?: Array<{ id: string; name: string; color: string }>\n): ProjectSummary {\n return {\n id: project.id,\n name: project.name,\n projectType: project.projectType,\n status: project.status,\n targetDate: project.targetDate,\n taskCount,\n ...(tags ? { tags } : {}),\n };\n}\n\nfunction toTaskSummary(task: Task): TaskSummary {\n return {\n id: task.id,\n title: task.title,\n status: task.status,\n priority: task.priority,\n dueDate: task.dueDate,\n assignee: task.assignee,\n tags: task.tags,\n };\n}\n\nexport const createProjectTool = {\n name: 'create_project',\n description: 'Create a new project roadmap. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n name: z.string().min(1, 'Project name is required'),\n description: z.string(),\n projectType: ProjectTypeEnum,\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format'),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n name: string;\n description: string;\n projectType: 'roadmap' | 'skill-tree' | 'kanban';\n startDate: string;\n targetDate: string;\n verbose?: boolean;\n }) {\n try {\n const projectInput: CreateProjectInput = {\n name: input.name,\n description: input.description,\n projectType: input.projectType,\n startDate: input.startDate,\n targetDate: input.targetDate,\n };\n const projectData = await storage.createProject(projectInput);\n return {\n success: true,\n data: input.verbose\n ? projectData\n : toProjectSummary(projectData.project, 0),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create project',\n };\n }\n },\n};\n\nexport const listProjectsTool = {\n name: 'list_projects',\n description: 'List all projects. Summary mode includes current project tags for Agent reuse. Set verbose=true for full project data.',\n inputSchema: z.object({\n verbose: z.boolean().optional(),\n }),\n async execute(input: { verbose?: boolean }) {\n try {\n const projects = await storage.listProjects();\n\n if (input.verbose) {\n return {\n success: true,\n data: projects,\n };\n }\n\n const summaries = await Promise.all(\n projects.map(async (projectSummary) => {\n const projectData = await storage.readProject(projectSummary.project.id);\n const tags = (projectData?.tags ?? []).map((tag) => ({\n id: tag.id,\n name: tag.name,\n color: tag.color,\n }));\n\n return toProjectSummary(projectSummary.project, projectSummary.taskCount, tags);\n })\n );\n\n return {\n success: true,\n data: summaries,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list projects',\n };\n }\n },\n};\n\nexport const getProjectTool = {\n name: 'get_project',\n description: 'Get a project by ID with all its data (tasks, tags, milestones). Tasks are returned as summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: { projectId: string; verbose?: boolean }) {\n try {\n const projectData = await storage.readProject(input.projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${input.projectId}' not found`,\n };\n }\n return {\n success: true,\n data: input.verbose\n ? projectData\n : {\n ...projectData,\n tasks: projectData.tasks.map(toTaskSummary),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get project',\n };\n }\n },\n};\n\nexport const updateProjectTool = {\n name: 'update_project',\n description: 'Update an existing project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n name: z.string().min(1).optional(),\n description: z.string().optional(),\n projectType: ProjectTypeEnum.optional(),\n status: ProjectStatusEnum.optional(),\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n name?: string;\n description?: string;\n projectType?: 'roadmap' | 'skill-tree' | 'kanban';\n status?: 'active' | 'completed' | 'archived';\n startDate?: string;\n targetDate?: string;\n verbose?: boolean;\n }) {\n try {\n const { projectId, verbose, ...updateData } = input;\n if (Object.keys(updateData).length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n };\n }\n const updateInput: UpdateProjectInput = updateData;\n const projectData = await storage.updateProject(projectId, updateInput);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n };\n }\n return {\n success: true,\n data: verbose\n ? projectData\n : toProjectSummary(projectData.project, projectData.tasks.length),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update project',\n };\n }\n },\n};\n\nexport const deleteProjectTool = {\n name: 'delete_project',\n description: 'Delete a project by ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n }),\n async execute(input: { projectId: string }) {\n try {\n const deleted = await storage.deleteProject(input.projectId);\n\n if (!deleted) {\n return {\n success: false,\n error: `Project with ID '${input.projectId}' not found`,\n };\n }\n\n return {\n success: true,\n data: { deleted: true },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete project',\n };\n }\n },\n};\n","import * as path from 'path';\nimport type {\n Project,\n ProjectData,\n Task,\n TaskSearchFilters,\n CreateProjectInput,\n UpdateProjectInput,\n} from '../models/index.js';\nimport { getStorageDir } from '../utils/path-helpers.js';\nimport { readJsonFile, writeJsonFile, ensureDir } from '../utils/file-helpers.js';\n\n/**\n * Storage class for managing roadmap-skill projects\n * Projects are stored as individual JSON files in ~/.roadmap-skill/projects/\n */\nexport class ProjectStorage {\n private storageDir: string;\n\n constructor() {\n this.storageDir = getStorageDir();\n }\n\n /**\n * Ensure the storage directory exists\n */\n async ensureDirectory(): Promise<void> {\n await ensureDir(this.storageDir);\n }\n\n /**\n * Get the file path for a project\n * @param projectId - The project ID\n * @returns Full path to the project JSON file\n */\n getFilePath(projectId: string): string {\n return path.join(this.storageDir, `${projectId}.json`);\n }\n\n /**\n * Create a new project\n * @param input - Project creation data\n * @returns The created project data\n */\n async createProject(input: CreateProjectInput): Promise<ProjectData> {\n await this.ensureDirectory();\n\n const now = new Date().toISOString();\n const projectId = `proj_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n const project: Project = {\n id: projectId,\n name: input.name,\n description: input.description,\n projectType: input.projectType,\n status: 'active',\n startDate: input.startDate,\n targetDate: input.targetDate,\n createdAt: now,\n updatedAt: now,\n };\n\n const projectData: ProjectData = {\n version: 1,\n project,\n milestones: [],\n tasks: [],\n tags: [],\n };\n\n const filePath = this.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return projectData;\n }\n\n /**\n * Read a project by ID\n * @param projectId - The project ID\n * @returns The project data or null if not found\n */\n async readProject(projectId: string): Promise<ProjectData | null> {\n try {\n const filePath = this.getFilePath(projectId);\n return await readJsonFile<ProjectData>(filePath);\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Update an existing project\n * @param projectId - The project ID\n * @param input - Project update data\n * @returns The updated project data or null if not found\n */\n async updateProject(\n projectId: string,\n input: UpdateProjectInput\n ): Promise<ProjectData | null> {\n const projectData = await this.readProject(projectId);\n if (!projectData) {\n return null;\n }\n\n const now = new Date().toISOString();\n\n projectData.project = {\n ...projectData.project,\n ...input,\n updatedAt: now,\n };\n\n const filePath = this.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return projectData;\n }\n\n /**\n * Delete a project by ID\n * @param projectId - The project ID\n * @returns True if deleted, false if not found\n */\n async deleteProject(projectId: string): Promise<boolean> {\n try {\n const filePath = this.getFilePath(projectId);\n const fs = await import('fs/promises');\n await fs.unlink(filePath);\n return true;\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n return false;\n }\n throw error;\n }\n }\n\n /**\n * List all projects sorted by updatedAt (descending)\n * @returns Array of project summaries (project + metadata)\n */\n async listProjects(): Promise<Array<{ project: Project; taskCount: number; milestoneCount: number }>> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const projects: Array<{ project: Project; taskCount: number; milestoneCount: number }> = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n projects.push({\n project: data.project,\n taskCount: data.tasks.length,\n milestoneCount: data.milestones.length,\n });\n } catch {\n // Skip invalid files\n continue;\n }\n }\n\n // Sort by updatedAt descending\n return projects.sort(\n (a, b) => new Date(b.project.updatedAt).getTime() - new Date(a.project.updatedAt).getTime()\n );\n }\n\n /**\n * Search tasks across all projects with filters\n * @param filters - Search filters\n * @returns Array of matching tasks with project context\n */\n async searchTasks(\n filters: TaskSearchFilters\n ): Promise<Array<{ task: Task; project: Project }>> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const results: Array<{ task: Task; project: Project }> = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n\n // Skip if project filter doesn't match\n if (filters.projectId && data.project.id !== filters.projectId) {\n continue;\n }\n\n for (const task of data.tasks) {\n // Apply filters\n if (filters.status && task.status !== filters.status) {\n continue;\n }\n if (filters.priority && task.priority !== filters.priority) {\n continue;\n }\n if (filters.assignee && task.assignee !== filters.assignee) {\n continue;\n }\n if (filters.dueBefore && task.dueDate && task.dueDate > filters.dueBefore) {\n continue;\n }\n if (filters.dueAfter && task.dueDate && task.dueDate < filters.dueAfter) {\n continue;\n }\n if (\n filters.tags &&\n filters.tags.length > 0 &&\n !filters.tags.some((tag) => task.tags.includes(tag))\n ) {\n continue;\n }\n if (\n filters.searchText &&\n !task.title.toLowerCase().includes(filters.searchText.toLowerCase()) &&\n !task.description.toLowerCase().includes(filters.searchText.toLowerCase())\n ) {\n continue;\n }\n\n // Filter completed tasks (done status) unless includeCompleted is explicitly true\n if (filters.includeCompleted !== true && task.status === 'done') {\n continue;\n }\n\n results.push({ task, project: data.project });\n }\n } catch {\n // Skip invalid files\n continue;\n }\n }\n\n return results;\n }\n\n async exportAllData(): Promise<{\n version: number;\n exportedAt: string;\n projects: ProjectData[];\n }> {\n await this.ensureDirectory();\n\n const fs = await import('fs/promises');\n const files = await fs.readdir(this.storageDir);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n\n const projects: ProjectData[] = [];\n\n for (const file of jsonFiles) {\n try {\n const filePath = path.join(this.storageDir, file);\n const data = await readJsonFile<ProjectData>(filePath);\n projects.push(data);\n } catch {\n continue;\n }\n }\n\n return {\n version: 1,\n exportedAt: new Date().toISOString(),\n projects,\n };\n }\n\n async importAllData(data: {\n version: number;\n exportedAt: string;\n projects: ProjectData[];\n }): Promise<{\n success: boolean;\n imported: number;\n errors: number;\n errorDetails: string[];\n }> {\n await this.ensureDirectory();\n\n let imported = 0;\n let errors = 0;\n const errorDetails: string[] = [];\n\n if (!data.projects || !Array.isArray(data.projects)) {\n throw new Error('Invalid backup data: projects array is required');\n }\n\n for (const projectData of data.projects) {\n try {\n if (!projectData.project || !projectData.project.id) {\n errors++;\n errorDetails.push('Skipping invalid project: missing project or id');\n continue;\n }\n\n const filePath = this.getFilePath(projectData.project.id);\n await writeJsonFile(filePath, projectData);\n imported++;\n } catch (error) {\n errors++;\n const errorMessage = error instanceof Error ? error.message : String(error);\n errorDetails.push(`Failed to import project ${projectData.project?.id || 'unknown'}: ${errorMessage}`);\n }\n }\n\n return {\n success: errors === 0,\n imported,\n errors,\n errorDetails,\n };\n }\n}\n\nexport const storage = new ProjectStorage();\n","import * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Get the storage directory for roadmap-skill projects\n * Returns: ~/.roadmap-skill/projects\n */\nexport function getStorageDir(): string {\n const homeDir = os.homedir();\n return path.join(homeDir, '.roadmap-skill', 'projects');\n}\n","import { z } from 'zod';\nimport { TaskService } from '../services/index.js';\nimport { storage } from '../storage/index.js';\nimport type { Task, TaskSummary } from '../models/index.js';\n\nconst TaskStatusEnum = z.enum(['todo', 'in-progress', 'review', 'done']);\nconst TaskPriorityEnum = z.enum(['low', 'medium', 'high', 'critical']);\n\nfunction toTaskSummary(task: Task): TaskSummary {\n return {\n id: task.id,\n title: task.title,\n status: task.status,\n priority: task.priority,\n dueDate: task.dueDate,\n assignee: task.assignee,\n tags: task.tags,\n };\n}\nexport const createTaskTool = {\n name: 'create_task',\n description: 'Create a new task in a project. tags must be existing tag IDs from the same project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n title: z.string().min(1, 'Task title is required'),\n description: z.string(),\n priority: TaskPriorityEnum.default('medium'),\n tags: z.array(z.string()).default([]),\n dueDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n assignee: z.string().optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n tags: string[];\n dueDate?: string;\n assignee?: string;\n verbose?: boolean;\n }) {\n const result = await TaskService.create(input.projectId, {\n title: input.title,\n description: input.description,\n priority: input.priority,\n tags: input.tags,\n dueDate: input.dueDate,\n assignee: input.assignee,\n });\n if (!result.success) return result;\n return {\n success: true,\n data: input.verbose ? result.data : toTaskSummary(result.data),\n };\n },\n};\n\nexport const listTasksTool = {\n name: 'list_tasks',\n description: 'List tasks with optional filters. By default, completed (done) tasks are excluded. Set includeCompleted=true to include them. Returns summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().optional(),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n assignee: z.string().optional(),\n dueBefore: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n dueAfter: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(),\n includeCompleted: z.boolean().optional(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId?: string;\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n verbose?: boolean;\n }) {\n try {\n const results = await storage.searchTasks({\n projectId: input.projectId,\n status: input.status,\n priority: input.priority,\n tags: input.tags,\n assignee: input.assignee,\n dueBefore: input.dueBefore,\n dueAfter: input.dueAfter,\n includeCompleted: input.includeCompleted,\n });\n const tasks = results.map((r) => r.task);\n return {\n success: true,\n data: input.verbose ? tasks : tasks.map(toTaskSummary),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tasks',\n };\n }\n },\n};\n\nexport const getTaskTool = {\n name: 'get_task',\n description: 'Get a specific task by project ID and task ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n }),\n async execute(input: { projectId: string; taskId: string }) {\n const result = await TaskService.get(input.projectId, input.taskId);\n return result;\n },\n};\n\nexport const updateTaskTool = {\n name: 'update_task',\n description: 'Update an existing task. tags must be existing tag IDs from the same project. Returns summary by default; set verbose=true for full data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n title: z.string().min(1).optional(),\n description: z.string().optional(),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n dueDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional().nullable(),\n assignee: z.string().optional().nullable(),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n taskId: string;\n title?: string;\n description?: string;\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n verbose?: boolean;\n }) {\n const { projectId, taskId, verbose, ...updateData } = input;\n const result = await TaskService.update(projectId, taskId, updateData);\n if (!result.success) return result;\n return {\n success: true,\n data: verbose ? result.data : toTaskSummary(result.data),\n };\n },\n};\n\nexport const deleteTaskTool = {\n name: 'delete_task',\n description: 'Delete a task by project ID and task ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskId: z.string().min(1, 'Task ID is required'),\n }),\n async execute(input: { projectId: string; taskId: string }) {\n const result = await TaskService.delete(input.projectId, input.taskId);\n\n // 保持向后兼容:将 data: undefined 转换为 { deleted: true }\n if (result.success) {\n return {\n success: true,\n data: { deleted: true },\n };\n }\n\n return result;\n },\n};\n\nexport const batchUpdateTasksTool = {\n name: 'batch_update_tasks',\n description: 'Update multiple tasks at once. tags must be existing tag IDs from the same project. Returns summaries by default; set verbose=true for full task data.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n taskIds: z.array(z.string()).min(1, 'At least one task ID is required'),\n status: TaskStatusEnum.optional(),\n priority: TaskPriorityEnum.optional(),\n tags: z.array(z.string()).optional(),\n tagOperation: z.enum(['add', 'remove', 'replace']).default('replace'),\n verbose: z.boolean().optional(),\n }),\n async execute(input: {\n projectId: string;\n taskIds: string[];\n status?: 'todo' | 'in-progress' | 'review' | 'done';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n tagOperation?: 'add' | 'remove' | 'replace';\n verbose?: boolean;\n }) {\n const { projectId, taskIds, tagOperation, verbose, ...restData } = input;\n const result = await TaskService.batchUpdate(projectId, taskIds, {\n ...restData,\n tagOperation,\n });\n if (!result.success) return result;\n return {\n success: true,\n data: {\n updatedTasks: verbose\n ? result.data.updatedTasks\n : result.data.updatedTasks.map(toTaskSummary),\n updatedCount: result.data.updatedCount,\n notFoundIds: result.data.notFoundIds,\n },\n };\n },\n};\n","export { TagService } from './tag-service.js';\nexport { TaskService } from './task-service.js';\nexport * from './types.js';\n","/**\n * Tag Service - Unified business logic for tag management\n * Extracted from tag-tools.ts for better separation of concerns\n */\n\nimport type { ProjectStorage } from '../storage/index.js';\nimport type { Tag, ProjectData } from '../models/index.js';\nimport type {\n ServiceResult,\n CreateTagData,\n UpdateTagData,\n DeleteTagResult,\n TasksByTagResult,\n} from './types.js';\n\n/**\n * Generate a unique tag ID\n * @returns Tag ID in format tag_${timestamp}_${random}\n */\nfunction generateTagId(): string {\n return `tag_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nconst HEX_COLOR_PATTERN = /^#[0-9A-Fa-f]{6}$/;\n\nconst TAG_COLOR_PALETTE = [\n '#FF6B6B',\n '#FF9F43',\n '#FDCB6E',\n '#6C5CE7',\n '#74B9FF',\n '#00B894',\n '#00CEC9',\n '#E17055',\n '#FAB1A0',\n '#55A3FF',\n '#A29BFE',\n '#FD79A8',\n];\n\nfunction hashTagName(value: string): number {\n let hash = 5381;\n for (const char of value.toLowerCase()) {\n hash = (hash * 33) ^ char.charCodeAt(0);\n }\n return Math.abs(hash >>> 0);\n}\n\nfunction resolveTagColor(tagName: string, inputColor?: string): string {\n if (inputColor) {\n return inputColor;\n }\n\n const normalizedTagName = tagName.trim();\n if (normalizedTagName.length === 0) {\n return TAG_COLOR_PALETTE[0];\n }\n\n const colorIndex = hashTagName(normalizedTagName) % TAG_COLOR_PALETTE.length;\n return TAG_COLOR_PALETTE[colorIndex];\n}\n\n/**\n * TagService - Handles all tag-related business logic\n */\nexport class TagService {\n private storage: ProjectStorage;\n\n constructor(storage: ProjectStorage) {\n this.storage = storage;\n }\n\n /**\n * Create a new tag in a project\n * @param projectId - The project ID\n * @param data - Tag creation data\n * @returns The created tag or error\n */\n async create(projectId: string, data: CreateTagData): Promise<ServiceResult<Tag>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check for duplicate tag name (case-insensitive)\n const existingTag = projectData.tags.find(\n (t) => t.name.toLowerCase() === data.name.toLowerCase()\n );\n if (existingTag) {\n return {\n success: false,\n error: `Tag with name '${data.name}' already exists in this project`,\n code: 'DUPLICATE_ERROR',\n };\n }\n\n const resolvedColor = resolveTagColor(data.name, data.color);\n if (!HEX_COLOR_PATTERN.test(resolvedColor)) {\n return {\n success: false,\n error: `Color must be a valid hex code (e.g., #FF5733), received '${resolvedColor}'`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const tag: Tag = {\n id: generateTagId(),\n name: data.name,\n color: resolvedColor,\n description: data.description || '',\n createdAt: now,\n };\n\n projectData.tags.push(tag);\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: tag,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * List all tags in a project\n * @param projectId - The project ID\n * @returns Array of tags or error\n */\n async list(projectId: string): Promise<ServiceResult<Tag[]>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskTagCounts = new Map<string, number>();\n for (const task of projectData.tasks) {\n for (const tagId of task.tags) {\n taskTagCounts.set(tagId, (taskTagCounts.get(tagId) ?? 0) + 1);\n }\n }\n\n return {\n success: true,\n data: projectData.tags.map((tag) => ({\n ...tag,\n taskCount: taskTagCounts.get(tag.id) ?? 0,\n })),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tags',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Update an existing tag\n * @param projectId - The project ID\n * @param tagId - The tag ID\n * @param data - Tag update data\n * @returns The updated tag or error\n */\n async update(\n projectId: string,\n tagId: string,\n data: UpdateTagData\n ): Promise<ServiceResult<Tag>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const tagIndex = projectData.tags.findIndex((t) => t.id === tagId);\n if (tagIndex === -1) {\n return {\n success: false,\n error: `Tag with ID '${tagId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check if there is any field to update\n if (Object.keys(data).length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n code: 'VALIDATION_ERROR',\n };\n }\n\n // Check for duplicate name if updating name (case-insensitive)\n if (data.name) {\n const existingTag = projectData.tags.find(\n (t) =>\n t.name.toLowerCase() === data.name!.toLowerCase() && t.id !== tagId\n );\n if (existingTag) {\n return {\n success: false,\n error: `Tag with name '${data.name}' already exists in this project`,\n code: 'DUPLICATE_ERROR',\n };\n }\n }\n\n if (data.color && !HEX_COLOR_PATTERN.test(data.color)) {\n return {\n success: false,\n error: `Color must be a valid hex code (e.g., #FF5733), received '${data.color}'`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const existingTag = projectData.tags[tagIndex];\n\n const updatedTag: Tag = {\n ...existingTag,\n ...data,\n id: existingTag.id,\n createdAt: existingTag.createdAt,\n };\n\n projectData.tags[tagIndex] = updatedTag;\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: updatedTag,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Delete a tag by ID\n * Also removes the tag from all tasks that use it\n * @param projectId - The project ID\n * @param tagId - The tag ID\n * @returns Delete result with tag info and count of updated tasks\n */\n async delete(projectId: string, tagId: string): Promise<ServiceResult<DeleteTagResult>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const tagIndex = projectData.tags.findIndex((t) => t.id === tagId);\n if (tagIndex === -1) {\n return {\n success: false,\n error: `Tag with ID '${tagId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n const tag = projectData.tags[tagIndex];\n\n // Remove tag from all tasks that use it\n const now = new Date().toISOString();\n let tasksUpdated = 0;\n for (const task of projectData.tasks) {\n const tagIndexInTask = task.tags.indexOf(tagId);\n if (tagIndexInTask !== -1) {\n task.tags.splice(tagIndexInTask, 1);\n task.updatedAt = now;\n tasksUpdated++;\n }\n }\n\n projectData.tags.splice(tagIndex, 1);\n projectData.project.updatedAt = now;\n\n await this.saveProjectData(projectId, projectData);\n\n return {\n success: true,\n data: {\n deleted: true,\n tag,\n tasksUpdated,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Get all tasks that have a specific tag by tag name\n * @param projectId - The project ID\n * @param tagName - The tag name\n * @returns Tag info and matching tasks\n */\n async getTasksByTag(\n projectId: string,\n tagName: string\n ): Promise<ServiceResult<TasksByTagResult>> {\n try {\n const projectData = await this.storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n // Find tag by name (case-insensitive)\n const tag = projectData.tags.find(\n (t) => t.name.toLowerCase() === tagName.toLowerCase()\n );\n\n if (!tag) {\n return {\n success: false,\n error: `Tag with name '${tagName}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Find all tasks with this tag\n const tasks = projectData.tasks.filter((t) => t.tags.includes(tag.id));\n\n return {\n success: true,\n data: {\n tag,\n tasks,\n count: tasks.length,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get tasks by tag',\n code: 'INTERNAL_ERROR',\n };\n }\n }\n\n /**\n * Helper method to save project data\n * @param projectId - The project ID\n * @param projectData - The project data to save\n */\n private async saveProjectData(projectId: string, projectData: ProjectData): Promise<void> {\n const filePath = this.storage.getFilePath(projectId);\n const { writeJsonFile } = await import('../utils/file-helpers.js');\n await writeJsonFile(filePath, projectData);\n }\n}\n","/**\n * Task Service - Unified business logic for task operations\n * Extracted from task-tools.ts to enable reuse across different interfaces\n */\n\nimport type { ProjectData, Task, TaskStatus } from '../models/index.js';\nimport { storage } from '../storage/index.js';\nimport { writeJsonFile } from '../utils/file-helpers.js';\nimport type {\n ServiceResult,\n CreateTaskData,\n UpdateTaskData,\n BatchUpdateTaskData,\n BatchUpdateResult,\n} from './types.js';\n\n/**\n * Generate a unique task ID\n * Format: task_${timestamp}_${random}\n */\nfunction generateTaskId(): string {\n return `task_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Calculate completedAt based on status change\n * - When status changes to 'done', set completedAt to current time\n * - When status changes from 'done' to other, clear completedAt\n * - Otherwise, preserve existing completedAt\n */\nfunction calculateCompletedAt(\n currentStatus: TaskStatus,\n newStatus: TaskStatus | undefined,\n existingCompletedAt: string | null,\n now: string\n): string | null {\n // Status is not being updated\n if (!newStatus) {\n return existingCompletedAt;\n }\n\n // Status changing to 'done'\n if (newStatus === 'done' && currentStatus !== 'done') {\n return now;\n }\n\n // Status changing from 'done' to something else\n if (currentStatus === 'done' && newStatus !== 'done') {\n return null;\n }\n\n // Status changing but not involving 'done' transition\n return existingCompletedAt;\n}\n\nfunction findInvalidTagIds(projectData: ProjectData, tagIds: string[]): string[] {\n const validTagIds = new Set(projectData.tags.map((tag) => tag.id));\n return tagIds.filter((tagId) => !validTagIds.has(tagId));\n}\n\n/**\n * TaskService - Business logic for task operations\n */\nexport const TaskService = {\n /**\n * Create a new task in a project\n * @param projectId - The project ID\n * @param data - Task creation data\n * @returns The created task or error\n */\n async create(projectId: string, data: CreateTaskData): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const incomingTagIds = data.tags ?? [];\n const invalidTagIds = findInvalidTagIds(projectData, incomingTagIds);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n\n const now = new Date().toISOString();\n const task: Task = {\n id: generateTaskId(),\n projectId,\n title: data.title,\n description: data.description,\n status: 'todo',\n priority: data.priority ?? 'medium',\n tags: incomingTagIds,\n dueDate: data.dueDate ?? null,\n assignee: data.assignee ?? null,\n createdAt: now,\n updatedAt: now,\n completedAt: null,\n };\n\n projectData.tasks.push(task);\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: task,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Get a specific task by project ID and task ID\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @returns The task or error\n */\n async get(projectId: string, taskId: string): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const task = projectData.tasks.find((t) => t.id === taskId);\n if (!task) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n return {\n success: true,\n data: task,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Update an existing task\n * Handles completedAt automatically based on status changes\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @param data - Task update data\n * @returns The updated task or error\n */\n async update(\n projectId: string,\n taskId: string,\n data: UpdateTaskData\n ): Promise<ServiceResult<Task>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n // Check if there's anything to update\n const updateKeys = Object.keys(data);\n if (updateKeys.length === 0) {\n return {\n success: false,\n error: 'At least one field to update is required',\n code: 'VALIDATION_ERROR',\n };\n }\n\n if (data.tags) {\n const invalidTagIds = findInvalidTagIds(projectData, data.tags);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n }\n\n const now = new Date().toISOString();\n const existingTask = projectData.tasks[taskIndex];\n\n // Calculate completedAt based on status change\n const completedAt = calculateCompletedAt(\n existingTask.status,\n data.status,\n existingTask.completedAt,\n now\n );\n\n const updatedTask: Task = {\n ...existingTask,\n ...data,\n id: existingTask.id,\n projectId: existingTask.projectId,\n createdAt: existingTask.createdAt,\n updatedAt: now,\n completedAt,\n };\n\n projectData.tasks[taskIndex] = updatedTask;\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: updatedTask,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Delete a task by project ID and task ID\n * @param projectId - The project ID\n * @param taskId - The task ID\n * @returns Void or error\n */\n async delete(projectId: string, taskId: string): Promise<ServiceResult<void>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n return {\n success: false,\n error: `Task with ID '${taskId}' not found in project '${projectId}'`,\n code: 'NOT_FOUND',\n };\n }\n\n const now = new Date().toISOString();\n projectData.tasks.splice(taskIndex, 1);\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: undefined,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete task',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * List tasks with optional filters\n * @param filters - Optional filters for the search\n * @returns Array of tasks or error\n */\n async list(filters?: {\n projectId?: string;\n status?: TaskStatus;\n priority?: 'low' | 'medium' | 'high' | 'critical';\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n }): Promise<ServiceResult<Task[]>> {\n try {\n const results = await storage.searchTasks({\n projectId: filters?.projectId,\n status: filters?.status,\n priority: filters?.priority,\n tags: filters?.tags,\n assignee: filters?.assignee,\n dueBefore: filters?.dueBefore,\n dueAfter: filters?.dueAfter,\n includeCompleted: filters?.includeCompleted,\n });\n\n // Extract just the tasks from the results\n const tasks = results.map((r) => r.task);\n\n return {\n success: true,\n data: tasks,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list tasks',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n\n /**\n * Update multiple tasks at once\n * @param projectId - The project ID\n * @param taskIds - Array of task IDs to update\n * @param data - Batch update data\n * @returns Batch update result or error\n */\n async batchUpdate(\n projectId: string,\n taskIds: string[],\n data: BatchUpdateTaskData\n ): Promise<ServiceResult<BatchUpdateResult>> {\n try {\n const projectData = await storage.readProject(projectId);\n if (!projectData) {\n return {\n success: false,\n error: `Project with ID '${projectId}' not found`,\n code: 'NOT_FOUND',\n };\n }\n\n const now = new Date().toISOString();\n const updatedTasks: Task[] = [];\n const notFoundIds: string[] = [];\n\n for (const taskId of taskIds) {\n const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);\n if (taskIndex === -1) {\n notFoundIds.push(taskId);\n continue;\n }\n\n const existingTask = projectData.tasks[taskIndex];\n let updatedTags = existingTask.tags ?? [];\n\n if (data.tags) {\n const invalidTagIds = findInvalidTagIds(projectData, data.tags);\n if (invalidTagIds.length > 0) {\n return {\n success: false,\n error: `Invalid tag IDs for project '${projectId}': ${invalidTagIds.join(', ')}`,\n code: 'VALIDATION_ERROR',\n };\n }\n }\n\n // Handle tags based on tagOperation\n if (data.tags) {\n const existingTags = existingTask.tags ?? [];\n switch (data.tagOperation) {\n case 'add':\n updatedTags = [...new Set([...existingTags, ...data.tags])];\n break;\n case 'remove':\n updatedTags = existingTags.filter((tag) => !data.tags!.includes(tag));\n break;\n case 'replace':\n default:\n updatedTags = data.tags;\n break;\n }\n }\n\n // Calculate completedAt based on status change\n const completedAt = calculateCompletedAt(\n existingTask.status,\n data.status,\n existingTask.completedAt,\n now\n );\n\n const updatedTask: Task = {\n ...existingTask,\n ...(data.status && { status: data.status }),\n ...(data.priority && { priority: data.priority }),\n tags: updatedTags,\n updatedAt: now,\n completedAt,\n };\n\n projectData.tasks[taskIndex] = updatedTask;\n updatedTasks.push(updatedTask);\n }\n\n if (updatedTasks.length === 0) {\n return {\n success: false,\n error: 'No tasks were found to update',\n code: 'NOT_FOUND',\n };\n }\n\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: {\n updatedTasks,\n updatedCount: updatedTasks.length,\n notFoundIds: notFoundIds.length > 0 ? notFoundIds : undefined,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to batch update tasks',\n code: 'INTERNAL_ERROR',\n };\n }\n },\n};\n","/**\n * Service layer type definitions\n * Provides unified result types and service interfaces\n */\n\nimport type { ProjectStorage } from '../storage/index.js';\nimport type { Task, Tag, TaskStatus, TaskPriority } from '../models/index.js';\n\n// ============================================================================\n// Result Types\n// ============================================================================\n\n/**\n * Error codes for service operations\n */\nexport type ErrorCode =\n | 'NOT_FOUND'\n | 'VALIDATION_ERROR'\n | 'DUPLICATE_ERROR'\n | 'UNAUTHORIZED'\n | 'INTERNAL_ERROR';\n\n/**\n * Service result type - discriminated union for success/failure\n */\nexport type ServiceResult<T> =\n | { success: true; data: T }\n | { success: false; error: string; code: ErrorCode };\n\n// ============================================================================\n// Task Service Types\n// ============================================================================\n\nexport interface CreateTaskData {\n title: string;\n description: string;\n priority?: TaskPriority;\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n}\n\nexport interface UpdateTaskData {\n title?: string;\n description?: string;\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n dueDate?: string | null;\n assignee?: string | null;\n}\n\nexport interface BatchUpdateTaskData {\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n tagOperation?: 'add' | 'remove' | 'replace';\n}\n\nexport interface BatchUpdateResult {\n updatedTasks: Task[];\n updatedCount: number;\n notFoundIds?: string[];\n}\n\n// ============================================================================\n// Tag Service Types\n// ============================================================================\n\nexport interface CreateTagData {\n name: string;\n color?: string;\n description?: string;\n}\n\nexport interface UpdateTagData {\n name?: string;\n color?: string;\n description?: string;\n}\n\nexport interface DeleteTagResult {\n deleted: true;\n tag: Tag;\n tasksUpdated: number;\n}\n\nexport interface TasksByTagResult {\n tag: Tag;\n tasks: Task[];\n count: number;\n}\n\n// ============================================================================\n// Service Context\n// ============================================================================\n\n/**\n * Service context for dependency injection\n */\nexport interface ServiceContext {\n storage: ProjectStorage;\n}\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\n/**\n * Task Service interface\n */\nexport interface ITaskService {\n create(projectId: string, data: CreateTaskData): Promise<ServiceResult<Task>>;\n get(projectId: string, taskId: string): Promise<ServiceResult<Task>>;\n update(projectId: string, taskId: string, data: UpdateTaskData): Promise<ServiceResult<Task>>;\n delete(projectId: string, taskId: string): Promise<ServiceResult<void>>;\n list(filters?: {\n projectId?: string;\n status?: TaskStatus;\n priority?: TaskPriority;\n tags?: string[];\n assignee?: string;\n dueBefore?: string;\n dueAfter?: string;\n includeCompleted?: boolean;\n }): Promise<ServiceResult<Task[]>>;\n batchUpdate(\n projectId: string,\n taskIds: string[],\n data: BatchUpdateTaskData\n ): Promise<ServiceResult<BatchUpdateResult>>;\n}\n\n/**\n * Tag Service interface\n */\nexport interface ITagService {\n create(projectId: string, data: CreateTagData): Promise<ServiceResult<Tag>>;\n list(projectId: string): Promise<ServiceResult<Tag[]>>;\n update(projectId: string, tagId: string, data: UpdateTagData): Promise<ServiceResult<Tag>>;\n delete(projectId: string, tagId: string): Promise<ServiceResult<DeleteTagResult>>;\n getTasksByTag(projectId: string, tagName: string): Promise<ServiceResult<TasksByTagResult>>;\n}\n","import { z } from 'zod';\nimport { TagService } from '../services/index.js';\nimport { storage } from '../storage/index.js';\n\nconst tagService = new TagService(storage);\n\nexport const createTagTool = {\n name: 'create_tag',\n description: 'Create a new tag in a project. If color is omitted, it is generated deterministically from tag name.',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n name: z.string().min(1, 'Tag name is required'),\n color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Color must be a valid hex code (e.g., #FF5733)').optional(),\n description: z.string().default(''),\n }),\n async execute(input: {\n projectId: string;\n name: string;\n color?: string;\n description: string;\n }) {\n const { projectId, ...data } = input;\n const result = await tagService.create(projectId, data);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const listTagsTool = {\n name: 'list_tags',\n description: 'List all tags in a project',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n }),\n async execute(input: { projectId: string }) {\n const result = await tagService.list(input.projectId);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const updateTagTool = {\n name: 'update_tag',\n description: 'Update an existing tag',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagId: z.string().min(1, 'Tag ID is required'),\n name: z.string().min(1).optional(),\n color: z.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),\n description: z.string().optional(),\n }),\n async execute(input: {\n projectId: string;\n tagId: string;\n name?: string;\n color?: string;\n description?: string;\n }) {\n const { projectId, tagId, ...data } = input;\n const result = await tagService.update(projectId, tagId, data);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const deleteTagTool = {\n name: 'delete_tag',\n description: 'Delete a tag by project ID and tag ID',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagId: z.string().min(1, 'Tag ID is required'),\n }),\n async execute(input: { projectId: string; tagId: string }) {\n const result = await tagService.delete(input.projectId, input.tagId);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n\nexport const getTasksByTagTool = {\n name: 'get_tasks_by_tag',\n description: 'Get all tasks that have a specific tag',\n inputSchema: z.object({\n projectId: z.string().min(1, 'Project ID is required'),\n tagName: z.string().min(1, 'Tag name is required'),\n }),\n async execute(input: { projectId: string; tagName: string }) {\n const result = await tagService.getTasksByTag(input.projectId, input.tagName);\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n return { success: true, data: result.data };\n },\n};\n","import { createServer } from '../web/server.js';\nimport open from 'open';\nimport type { Server } from 'http';\n\nlet activeServer: Server | null = null;\nlet activePort: number | null = null;\n\nfunction getServerPort(server: Server): number | null {\n const address = server.address();\n\n if (address && typeof address === 'object' && 'port' in address) {\n return typeof address.port === 'number' ? address.port : null;\n }\n\n return null;\n}\n\nasync function closeServer(server: Server): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n\n const forceCloseServer = server as {\n closeAllConnections?: () => void;\n closeIdleConnections?: () => void;\n };\n forceCloseServer.closeIdleConnections?.();\n forceCloseServer.closeAllConnections?.();\n });\n}\n\nasync function openBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch (error) {\n console.error('Failed to open browser:', error);\n }\n}\n\nexport const openWebInterfaceTool = {\n name: 'open_web_interface',\n description: 'Open web visualization interface',\n parameters: {\n type: 'object',\n properties: {\n port: {\n type: 'number',\n description: 'Port to run the web interface on (default: 7860)',\n },\n },\n },\n async execute(args: { port?: number }) {\n const requestedPort = args.port || 7860;\n\n if (activeServer) {\n const runningPort = getServerPort(activeServer) ?? activePort;\n\n if (runningPort !== requestedPort) {\n throw new Error(`Web interface is already running on port ${runningPort ?? 'unknown'}. Please close it before opening a different port.`);\n }\n\n const url = `http://localhost:${runningPort ?? requestedPort}`;\n await openBrowser(url);\n\n return { \n message: 'Web interface is already running',\n url,\n };\n }\n\n const url = `http://localhost:${requestedPort}`;\n\n try {\n activeServer = await createServer(requestedPort);\n activePort = requestedPort;\n await openBrowser(url);\n\n return {\n message: 'Web interface started successfully and opened in browser',\n url,\n };\n } catch (error) {\n activeServer = null;\n activePort = null;\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to start web interface: ${errorMessage}`);\n }\n }\n};\n\nexport const closeWebInterfaceTool = {\n name: 'close_web_interface',\n description: 'Close web visualization interface',\n parameters: {\n type: 'object',\n properties: {},\n },\n async execute() {\n if (!activeServer) {\n return { message: 'Web interface is not running' };\n }\n\n try {\n await closeServer(activeServer);\n activeServer = null;\n activePort = null;\n return { message: 'Web interface stopped' };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to stop web interface: ${errorMessage}`);\n }\n }\n};\n","import express from 'express';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createRequire } from 'node:module';\nimport { existsSync } from 'node:fs';\nimport type { Server } from 'http';\nimport { storage } from '../storage/index.js';\nimport { TaskService, TagService } from '../services/index.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Resolve the path to the web app static files using multiple fallback strategies.\n * Handles npx execution, global installation, local development, and bundled execution.\n */\nfunction resolveAppPath(): string {\n const candidates: Array<{ path: string; source: string }> = [];\n\n try {\n const require = createRequire(import.meta.url);\n const pkgRoot = path.dirname(require.resolve('../../package.json'));\n candidates.push({ path: path.join(pkgRoot, 'dist/web/app'), source: 'package.json resolve' });\n } catch {\n // Package.json not resolvable\n }\n\n // Primary path when bundled: __dirname = dist/, so dist/web/app is correct\n candidates.push({ path: path.join(__dirname, 'web/app'), source: '__dirname/web/app' });\n candidates.push({ path: path.join(__dirname, 'app'), source: '__dirname relative' });\n candidates.push({ path: path.join(process.cwd(), 'dist/web/app'), source: 'process.cwd()' });\n candidates.push({ path: path.join(__dirname, '../web/app'), source: '__dirname/../web/app' });\n\n for (const { path: candidatePath, source } of candidates) {\n const indexPath = path.join(candidatePath, 'index.html');\n if (existsSync(indexPath)) {\n console.error(`[roadmap-skill] Static files found at: ${candidatePath} (via ${source})`);\n return candidatePath;\n }\n }\n\n const triedPaths = candidates.map(c => ` - ${c.path} (${c.source})`).join('\\n');\n throw new Error(\n `Cannot find web app static files.\\n\\n` +\n `Tried:\\n${triedPaths}\\n\\n` +\n `Ensure the package is installed correctly and web assets exist.`\n );\n}\n\nconst tagService = new TagService(storage);\n\nexport function createServer(port: number = 7860): Promise<Server> {\n return new Promise((resolve, reject) => {\n const app = express();\n\n app.use(express.json());\n\n app.get('/api/projects', async (_req, res) => {\n try {\n const projects = await storage.listProjects();\n res.json(projects);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/projects/:id', async (req, res) => {\n try {\n const project = await storage.readProject(req.params.id);\n if (!project) {\n res.status(404).json({ error: 'Project not found' });\n return;\n }\n res.json(project);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/tasks', async (req, res) => {\n try {\n const filters: Record<string, unknown> = { ...req.query };\n\n // Convert includeCompleted from string to boolean\n if (filters.includeCompleted !== undefined) {\n filters.includeCompleted = filters.includeCompleted === 'true';\n }\n\n const tasks = await storage.searchTasks(filters as any);\n res.json(tasks);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/projects', async (req, res) => {\n try {\n const project = await storage.createProject(req.body);\n res.json({ success: true, data: project });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/projects', async (req, res) => {\n try {\n const { projectId, ...updateData } = req.body;\n const project = await storage.updateProject(projectId, updateData);\n res.json({ success: true, data: project });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/projects', async (req, res) => {\n try {\n const { projectId } = req.query;\n await storage.deleteProject(projectId as string);\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/tasks', async (req, res) => {\n try {\n const { projectId, ...taskData } = req.body;\n const result = await TaskService.create(projectId, taskData);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/tasks', async (req, res) => {\n try {\n const { projectId, taskId, ...updateData } = req.body;\n const result = await TaskService.update(projectId, taskId, updateData);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/tasks', async (req, res) => {\n try {\n const { projectId, taskId } = req.query;\n const result = await TaskService.delete(projectId as string, taskId as string);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/projects/:projectId/tags', async (req, res) => {\n try {\n const { projectId } = req.params;\n const result = await tagService.create(projectId, req.body);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/projects/:projectId/tags', async (req, res) => {\n try {\n const { projectId } = req.params;\n const result = await tagService.list(projectId);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.put('/api/projects/:projectId/tags/:tagId', async (req, res) => {\n try {\n const { projectId, tagId } = req.params;\n const result = await tagService.update(projectId, tagId, req.body);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.delete('/api/projects/:projectId/tags/:tagId', async (req, res) => {\n try {\n const { projectId, tagId } = req.params;\n const result = await tagService.delete(projectId, tagId);\n if (!result.success) {\n const statusCode = result.code === 'NOT_FOUND' ? 404 : 400;\n res.status(statusCode).json({ error: result.error });\n return;\n }\n res.json({ success: true, data: result.data });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/backup', async (_req, res) => {\n try {\n const backup = await storage.exportAllData();\n const filename = `roadmap-skill-backup-${new Date().toISOString().split('T')[0]}.json`;\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Content-Disposition', `attachment; filename=\"${filename}\"`);\n res.json(backup);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.post('/api/backup', async (req, res) => {\n try {\n const result = await storage.importAllData(req.body);\n res.json(result);\n } catch (error) {\n res.status(400).json({\n success: false,\n error: (error as Error).message,\n });\n }\n });\n\n const distPath = resolveAppPath();\n app.use(express.static(distPath));\n\n app.get('*', (req, res) => {\n if (req.path.startsWith('/api')) {\n res.status(404).json({ error: 'API not found' });\n return;\n }\n res.sendFile(path.join(distPath, 'index.html'));\n });\n\n const server = app.listen(port, '127.0.0.1');\n\n server.once('listening', () => {\n console.error(`Web interface server running at http://localhost:${port}`);\n resolve(server);\n });\n\n server.once('error', (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use`));\n return;\n }\n\n reject(error);\n });\n });\n}\n\n// Start server if run directly\nif (process.argv[1]?.endsWith('server.js')) {\n const port = parseInt(process.argv[2] || '7860', 10);\n createServer(port).catch(err => {\n console.error('Failed to start server:', err);\n process.exit(1);\n });\n}\n","import { z } from 'zod';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { storage } from '../storage/index.js';\nimport type { CreateProjectInput, Tag, Task } from '../models/index.js';\n\nconst TEMPLATES_DIR = path.join(process.cwd(), 'templates');\n\ninterface TemplateMetadata {\n name: string;\n description: string;\n projectType: string;\n tasks: Array<{\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n tags: string[];\n estimatedHours?: number;\n }>;\n tags: Array<{\n name: string;\n color: string;\n }>;\n}\n\nasync function getTemplateFiles(): Promise<string[]> {\n try {\n const files = await fs.readdir(TEMPLATES_DIR);\n return files.filter((f) => f.endsWith('.json'));\n } catch {\n return [];\n }\n}\n\nasync function loadTemplate(templateName: string): Promise<TemplateMetadata | null> {\n try {\n const fileName = templateName.endsWith('.json') ? templateName : `${templateName}.json`;\n const filePath = path.join(TEMPLATES_DIR, fileName);\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as TemplateMetadata;\n } catch {\n return null;\n }\n}\n\nfunction generateId(prefix: string): string {\n return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport const listTemplatesTool = {\n name: 'list_templates',\n description: 'List all available project templates',\n inputSchema: z.object({}),\n async execute() {\n try {\n const templateFiles = await getTemplateFiles();\n const templates = [];\n\n for (const file of templateFiles) {\n const template = await loadTemplate(file);\n if (template) {\n templates.push({\n name: file.replace('.json', ''),\n displayName: template.name,\n description: template.description,\n projectType: template.projectType,\n taskCount: template.tasks.length,\n tagCount: template.tags.length,\n });\n }\n }\n\n return {\n success: true,\n data: templates,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to list templates',\n };\n }\n },\n};\n\nexport const getTemplateTool = {\n name: 'get_template',\n description: 'Get detailed information about a specific template',\n inputSchema: z.object({\n templateName: z.string().min(1, 'Template name is required'),\n }),\n async execute(input: { templateName: string }) {\n try {\n const template = await loadTemplate(input.templateName);\n\n if (!template) {\n return {\n success: false,\n error: `Template '${input.templateName}' not found`,\n };\n }\n\n return {\n success: true,\n data: {\n name: template.name,\n description: template.description,\n projectType: template.projectType,\n tasks: template.tasks.map((t) => ({\n title: t.title,\n description: t.description,\n priority: t.priority,\n tags: t.tags,\n estimatedHours: t.estimatedHours,\n })),\n tags: template.tags,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to get template',\n };\n }\n },\n};\n\nexport const applyTemplateTool = {\n name: 'apply_template',\n description: 'Create a new project from a template',\n inputSchema: z.object({\n templateName: z.string().min(1, 'Template name is required'),\n projectName: z.string().min(1, 'Project name is required'),\n description: z.string().default(''),\n startDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format').optional(),\n targetDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'Date must be in YYYY-MM-DD format').optional(),\n }),\n async execute(input: {\n templateName: string;\n projectName: string;\n description: string;\n startDate?: string;\n targetDate?: string;\n }) {\n try {\n const template = await loadTemplate(input.templateName);\n\n if (!template) {\n return {\n success: false,\n error: `Template '${input.templateName}' not found`,\n };\n }\n\n const projectInput: CreateProjectInput = {\n name: input.projectName,\n description: input.description || template.description,\n projectType: template.projectType as 'roadmap' | 'skill-tree' | 'kanban',\n startDate: input.startDate || new Date().toISOString().split('T')[0],\n targetDate: input.targetDate || new Date().toISOString().split('T')[0],\n };\n\n const projectData = await storage.createProject(projectInput);\n const projectId = projectData.project.id;\n const now = new Date().toISOString();\n\n const tagNameToId: Map<string, string> = new Map();\n const tags: Tag[] = [];\n\n for (const templateTag of template.tags) {\n const tag: Tag = {\n id: generateId('tag'),\n name: templateTag.name,\n color: templateTag.color,\n description: '',\n createdAt: now,\n };\n tags.push(tag);\n tagNameToId.set(templateTag.name, tag.id);\n }\n\n const tasks: Task[] = [];\n\n for (const templateTask of template.tasks) {\n const taskTagIds = templateTask.tags\n .map((tagName) => tagNameToId.get(tagName))\n .filter((id): id is string => id !== undefined);\n\n const task: Task = {\n id: generateId('task'),\n projectId,\n title: templateTask.title,\n description: templateTask.description,\n status: 'todo',\n priority: templateTask.priority,\n tags: taskTagIds,\n dueDate: null,\n assignee: null,\n createdAt: now,\n updatedAt: now,\n completedAt: null,\n };\n tasks.push(task);\n }\n\n projectData.tags = tags;\n projectData.tasks = tasks;\n projectData.project.updatedAt = now;\n\n const filePath = storage.getFilePath(projectId);\n const { writeJsonFile } = await import('../utils/file-helpers.js');\n await writeJsonFile(filePath, projectData);\n\n return {\n success: true,\n data: {\n project: projectData.project,\n taskCount: tasks.length,\n tagCount: tags.length,\n tasksCreated: tasks.map((t) => ({\n id: t.id,\n title: t.title,\n priority: t.priority,\n })),\n tagsCreated: tags.map((t) => ({\n id: t.id,\n name: t.name,\n color: t.color,\n })),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to apply template',\n };\n }\n },\n};\n","export {\n projectResources,\n handleResourceRequest,\n getAllResources,\n} from './project-resources.js';\n","import type {\n Resource,\n TextResourceContents,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { storage } from '../storage/index.js';\n\n/**\n * Resource definitions for roadmap projects\n */\nexport const projectResources: Resource[] = [\n {\n uri: 'roadmap://projects',\n name: 'Project List',\n mimeType: 'application/json',\n description: 'Returns a list of all projects with basic metadata',\n },\n {\n uri: 'roadmap://project/{projectId}',\n name: 'Project Details',\n mimeType: 'application/json',\n description: 'Returns detailed information about a specific project including tasks, milestones, and tags',\n },\n {\n uri: 'roadmap://project/{projectId}/tasks',\n name: 'Project Tasks',\n mimeType: 'application/json',\n description: 'Returns all tasks for a specific project',\n },\n {\n uri: 'roadmap://project/{projectId}/progress',\n name: 'Project Progress',\n mimeType: 'application/json',\n description: 'Returns progress statistics for a specific project',\n },\n];\n\n/**\n * Resource URI patterns for matching\n */\nconst RESOURCE_PATTERNS = {\n projectList: /^roadmap:\\/\\/projects$/,\n projectDetails: /^roadmap:\\/\\/project\\/([^/]+)$/,\n projectTasks: /^roadmap:\\/\\/project\\/([^/]+)\\/tasks$/,\n projectProgress: /^roadmap:\\/\\/project\\/([^/]+)\\/progress$/,\n};\n\n/**\n * Handle resource requests\n * @param uri - The resource URI\n * @returns Resource contents or null if not found\n */\nexport async function handleResourceRequest(\n uri: string\n): Promise<TextResourceContents | null> {\n // Project List: roadmap://projects\n if (RESOURCE_PATTERNS.projectList.test(uri)) {\n return await getProjectListResource(uri);\n }\n\n // Project Details: roadmap://project/{projectId}\n const projectDetailsMatch = uri.match(RESOURCE_PATTERNS.projectDetails);\n if (projectDetailsMatch && !uri.includes('/tasks') && !uri.includes('/progress')) {\n const projectId = projectDetailsMatch[1];\n return await getProjectDetailsResource(uri, projectId);\n }\n\n // Project Tasks: roadmap://project/{projectId}/tasks\n const projectTasksMatch = uri.match(RESOURCE_PATTERNS.projectTasks);\n if (projectTasksMatch) {\n const projectId = projectTasksMatch[1];\n return await getProjectTasksResource(uri, projectId);\n }\n\n // Project Progress: roadmap://project/{projectId}/progress\n const projectProgressMatch = uri.match(RESOURCE_PATTERNS.projectProgress);\n if (projectProgressMatch) {\n const projectId = projectProgressMatch[1];\n return await getProjectProgressResource(uri, projectId);\n }\n\n return null;\n}\n\n/**\n * Get project list resource\n */\nasync function getProjectListResource(uri: string): Promise<TextResourceContents> {\n const projects = await storage.listProjects();\n\n const data = {\n projects: projects.map(p => ({\n id: p.project.id,\n name: p.project.name,\n description: p.project.description,\n status: p.project.status,\n projectType: p.project.projectType,\n taskCount: p.taskCount,\n milestoneCount: p.milestoneCount,\n updatedAt: p.project.updatedAt,\n })),\n totalCount: projects.length,\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project details resource\n */\nasync function getProjectDetailsResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const data = {\n project: projectData.project,\n milestones: projectData.milestones,\n tasks: projectData.tasks,\n tags: projectData.tags,\n stats: {\n taskCount: projectData.tasks.length,\n milestoneCount: projectData.milestones.length,\n tagCount: projectData.tags.length,\n completedTasks: projectData.tasks.filter(t => t.status === 'done').length,\n inProgressTasks: projectData.tasks.filter(t => t.status === 'in-progress').length,\n },\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project tasks resource\n */\nasync function getProjectTasksResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const tasksByStatus = {\n todo: projectData.tasks.filter(t => t.status === 'todo'),\n inProgress: projectData.tasks.filter(t => t.status === 'in-progress'),\n review: projectData.tasks.filter(t => t.status === 'review'),\n done: projectData.tasks.filter(t => t.status === 'done'),\n };\n\n const data = {\n projectId,\n projectName: projectData.project.name,\n tasks: projectData.tasks,\n tasksByStatus,\n summary: {\n total: projectData.tasks.length,\n todo: tasksByStatus.todo.length,\n inProgress: tasksByStatus.inProgress.length,\n review: tasksByStatus.review.length,\n done: tasksByStatus.done.length,\n },\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Get project progress resource\n */\nasync function getProjectProgressResource(\n uri: string,\n projectId: string\n): Promise<TextResourceContents | null> {\n const projectData = await storage.readProject(projectId);\n\n if (!projectData) {\n return null;\n }\n\n const tasks = projectData.tasks;\n const totalTasks = tasks.length;\n const completedTasks = tasks.filter(t => t.status === 'done').length;\n const inProgressTasks = tasks.filter(t => t.status === 'in-progress').length;\n const reviewTasks = tasks.filter(t => t.status === 'review').length;\n const todoTasks = tasks.filter(t => t.status === 'todo').length;\n\n const completionPercentage = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;\n\n const milestones = projectData.milestones;\n const completedMilestones = milestones.filter(m => m.completedAt !== null).length;\n const milestoneProgress = milestones.length > 0 ? Math.round((completedMilestones / milestones.length) * 100) : 0;\n\n // Calculate overdue tasks\n const now = new Date().toISOString();\n const overdueTasks = tasks.filter(t => \n t.dueDate && \n t.dueDate < now && \n t.status !== 'done'\n );\n\n // Priority breakdown\n const priorityBreakdown = {\n critical: tasks.filter(t => t.priority === 'critical').length,\n high: tasks.filter(t => t.priority === 'high').length,\n medium: tasks.filter(t => t.priority === 'medium').length,\n low: tasks.filter(t => t.priority === 'low').length,\n };\n\n const data = {\n projectId,\n projectName: projectData.project.name,\n projectStatus: projectData.project.status,\n dates: {\n startDate: projectData.project.startDate,\n targetDate: projectData.project.targetDate,\n daysRemaining: calculateDaysRemaining(projectData.project.targetDate),\n },\n taskProgress: {\n total: totalTasks,\n completed: completedTasks,\n inProgress: inProgressTasks,\n review: reviewTasks,\n todo: todoTasks,\n completionPercentage,\n },\n milestoneProgress: {\n total: milestones.length,\n completed: completedMilestones,\n percentage: milestoneProgress,\n },\n overdueTasks: {\n count: overdueTasks.length,\n tasks: overdueTasks.map(t => ({\n id: t.id,\n title: t.title,\n dueDate: t.dueDate,\n status: t.status,\n })),\n },\n priorityBreakdown,\n lastUpdated: projectData.project.updatedAt,\n };\n\n return {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2),\n };\n}\n\n/**\n * Calculate days remaining until target date\n */\nfunction calculateDaysRemaining(targetDate: string): number | null {\n const target = new Date(targetDate);\n const now = new Date();\n const diffTime = target.getTime() - now.getTime();\n const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n return diffDays > 0 ? diffDays : null;\n}\n\n/**\n * Get all available resources\n */\nexport function getAllResources(): Resource[] {\n return projectResources;\n}\n","export {\n projectPrompts,\n getRecommendNextTasksPrompt,\n getAutoPrioritizePrompt,\n getEnhanceTaskDetailsPrompt,\n getQuickCapturePrompt,\n getPromptByName,\n getAllPrompts,\n} from './project-prompts.js';\n","import type {\n Prompt,\n GetPromptResult,\n} from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Curated Prompts - Help Agents use Roadmap Skill more intelligently\n */\nexport const projectPrompts: Prompt[] = [\n {\n name: 'suggest-tasks',\n description: 'Intelligently recommend the next priority tasks based on urgency, due dates, and project status',\n arguments: [\n {\n name: 'projectId',\n description: 'Specific project ID (optional; if not provided, auto-detect from current context or analyze all projects)',\n required: false,\n },\n {\n name: 'limit',\n description: 'Number of tasks to recommend (default: 3)',\n required: false,\n },\n ],\n },\n {\n name: 'auto-prioritize',\n description: 'Automatically analyze tasks and intelligently adjust priorities, considering due dates, dependencies, and project importance',\n arguments: [\n {\n name: 'projectId',\n description: 'Specific project ID (optional; if not provided, auto-detect from current context or analyze all projects)',\n required: false,\n },\n ],\n },\n {\n name: 'add-task-details',\n description: 'Intelligently enhance task details, including description, acceptance criteria, subtasks, and required resources',\n arguments: [\n {\n name: 'taskId',\n description: 'Task ID to be enhanced',\n required: true,\n },\n ],\n },\n {\n name: 'quick-capture',\n description: 'Quickly capture ideas/tasks, auto-categorize and suggest priorities',\n arguments: [\n {\n name: 'idea',\n description: 'Idea or task description to be captured',\n required: true,\n },\n {\n name: 'projectId',\n description: 'Target project ID (optional; if not provided, auto-detect from current context)',\n required: false,\n },\n ],\n },\n {\n name: 'open-web-ui',\n description: 'Open the web visualization interface for the roadmap skill',\n arguments: [\n {\n name: 'port',\n description: 'Port to run the web interface on (optional, default: 7860)',\n required: false,\n },\n ],\n },\n];\n\n/**\n * Intelligently recommend next tasks\n * Analyze all tasks and recommend optimal execution order based on priority, due dates, and dependencies\n */\nexport function getRecommendNextTasksPrompt(projectId?: string, limit?: string): GetPromptResult {\n const projectHint = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, focus on that project; otherwise, analyze all active projects';\n const taskLimit = limit ? parseInt(limit, 10) : 3;\n\n return {\n description: 'Intelligent Task Recommendation Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `${projectHint}, please recommend the ${taskLimit} tasks I should prioritize next.\n\n## Recommendation Logic (sorted by priority):\n\n### 1. Urgent and Important (Critical priority + Near due date)\n- Critical tasks due today or tomorrow\n- Overdue high-priority tasks\n\n### 2. High-Value Tasks (High priority + Clear due date)\n- High priority tasks due this week\n- Critical path tasks blocking other work\n\n### 3. Quick Wins (Medium priority + Short estimated time)\n- Medium tasks completable in 1-2 hours\n- Tasks that can significantly boost project progress\n\n### 4. Planned Work\n- Tasks marked \"in-progress\" but not yet completed\n- Normal priority tasks due soon\n\n## Please perform the following steps:\n\n1. **List all pending tasks** (status = todo or in-progress)\n2. **Filter high-priority tasks**: critical and high\n3. **Check due dates**: Identify tasks due soon or overdue\n4. **Analyze blocking relationships**: Identify tasks blocking others\n5. **Generate recommendation list**: Provide ${taskLimit} tasks to prioritize with reasons\n\n## Output Format:\n\n### Immediate Action (Critical)\n1. **Task Name** (Project Name)\n - Reason: [Why this task is most urgent]\n - Suggested Action: [What specifically to do]\n\n### Today's Focus (High)\n2. **Task Name** (Project Name)\n - Reason: [Why this task is important]\n - Suggested Action: [What specifically to do]\n\n### Follow-up\n3. **Task Name** (Project Name)\n - Reason: [Why this should be done next]\n - Suggested Action: [What specifically to do]\n\nPlease use the list_tasks tool to fetch task data, then provide intelligent recommendations.\n\n## Important Reminder\nWhen you start working on recommended tasks, please:\n1. Use update_task to set task status to in-progress\n2. After completing the task, use update_task to set status to done\n3. If blocked or have issues, document in description and update status to review\n\nKeep task status synchronized with actual progress!`,\n },\n },\n ],\n };\n}\n\n/**\n * Automatic Priority Optimization\n * Automatically adjust priorities based on due dates, project progress, and task dependencies\n */\nexport function getAutoPrioritizePrompt(projectId?: string): GetPromptResult {\n const projectHint = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, focus on that project; otherwise, analyze all active projects';\n\n return {\n description: 'Intelligent Priority Optimization Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `${projectHint}, please automatically analyze and adjust priorities.\n\n## Priority Adjustment Rules:\n\n### Conditions to Upgrade to Critical:\n- [ ] Due within 48 hours and not completed\n- [ ] Blocking other high/critical tasks\n- [ ] On project critical path and behind schedule\n- [ ] Has external dependencies (e.g., clients, partners) and time is tight\n\n### Conditions to Upgrade to High:\n- [ ] Due within 1 week\n- [ ] Prerequisite for important milestone\n- [ ] Stuck in \"in-progress\" state for too long (over 3 days)\n- [ ] Affects work of multiple team members\n\n### Conditions to Downgrade to Medium/Low:\n- [ ] Due date is far away (>2 weeks) and no dependencies\n- [ ] \"Nice to have\" feature rather than core functionality\n- [ ] Not needed in current phase, can be postponed\n\n### Other Considerations:\n- **Overall project progress**: Tasks for behind-schedule projects should be prioritized higher\n- **Resource availability**: If resources are tight, focus on highest priority\n- **Risk factors**: High-risk tasks should be addressed earlier\n\n## Please perform the following steps:\n\n1. **Get all tasks**: Use list_tasks to fetch task list\n2. **Analyze each task**:\n - Check gap between due date and current date\n - Identify task dependency relationships\n - Evaluate overall project health\n3. **Generate adjustment suggestions**: List tasks needing priority changes with reasons\n4. **Batch update**: Use batch_update_tasks to execute priority adjustments immediately — no confirmation needed\n\n## Output Format:\n\n### Suggested Upgrade to Critical\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | high → critical | Due tomorrow |\n\n### Suggested Upgrade to High\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | medium → high | Blocking follow-up tasks |\n\n### Suggested Downgrade\n| Task | Current Priority | Suggested Priority | Reason |\n|------|-----------------|-------------------|--------|\n| XXX | high → medium | Can be postponed |\n\n### Keep Unchanged (Priorities are reasonable)\n- List tasks with reasonable priority settings\n\nPlease provide analysis results and immediately execute batch_update_tasks to apply the priority adjustments — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Intelligent Task Detail Enhancement\n * Auto-complete descriptions, acceptance criteria, etc. based on task title and context\n */\nexport function getEnhanceTaskDetailsPrompt(taskId: string): GetPromptResult {\n return {\n description: 'Task Detail Enhancement Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please help me enhance the details for task ${taskId}.\n\n## Enhancement Content:\n\n### 1. Detailed Description\n- Specific content and background of the task\n- Why this task needs to be done\n- Expected business or technical value\n\n### 2. Acceptance Criteria (Definition of Done)\nList clear completion standards, for example:\n- [ ] Feature implemented and locally tested\n- [ ] Code passes Code Review\n- [ ] Related documentation updated\n- [ ] Unit test coverage > 80%\n\n### 3. Technical/Implementation Details\n- Tech stack or modules involved\n- Files that may need modification\n- Potential challenges or considerations\n\n### 4. Related Resources\n- Related documentation links\n- Reference implementations or example code\n- People to consult\n\n### 5. Subtask Suggestions (if needed)\nIf the task is complex, suggest breaking it down:\n- Subtask 1: ...\n- Subtask 2: ...\n- Subtask 3: ...\n\n## Please perform the following steps:\n\n1. **Get task info**: Use get_task to view current task details\n2. **Get project context**: Use get_project to understand project background\n3. **Analyze task type**:\n - If development task: Add technical details, code locations\n - If design task: Add design specs, review criteria\n - If documentation task: Add doc structure, references\n - If testing task: Add test scenarios, coverage scope\n4. **Apply enhancement**: Use update_task to update task description immediately — no confirmation needed\n\n## Updated task should include:\n\n\\`\\`\\`\n## Background\n[Task background and purpose]\n\n## Acceptance Criteria\n- [ ] [Standard 1]\n- [ ] [Standard 2]\n- [ ] [Standard 3]\n\n## Technical Details\n- Modules: [module name]\n- Key files: [file path]\n- Notes: [important reminders]\n\n## Related Resources\n- Documentation: [link]\n- References: [link]\n\\`\\`\\`\n\nPlease fetch task info and immediately use update_task to apply the enhanced details — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Quick Idea Capture\n * Auto-categorize, suggest priorities, recommend projects\n */\nexport function getQuickCapturePrompt(idea: string, projectId?: string): GetPromptResult {\n const projectContext = projectId\n ? `User specified project: ${projectId}. Use this project if it exists, or inform user if not found.`\n : 'User did not specify a project. Based on the current working directory and conversation context, try to identify the most relevant project. If a clear match exists, use that project; otherwise, analyze all active projects and select the best match';\n\n return {\n description: 'Quick Capture Assistant',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `I want to quickly capture an idea/task: \"${idea}\"\n\n${projectContext}\n\n## [Non-intrusive task] Pause your current work briefly to complete this quick capture, then let the user know it's done and resume what you were doing.\n\n## Please complete the following steps immediately:\n\n### 1. Task Information Extraction\nExtract from description:\n- **Task Title**: Concise and clear title (start with verb)\n- **Task Description**: Add context and details\n- **Task Type**: bug / feature / refactor / docs / chore\n- **Estimated Priority**: critical / high / medium / low (based on urgency in description)\n\n### 2. Project Selection (if no project specified)\n- List all active projects\n- Analyze which project the task content is most relevant to\n- Select the most suitable project automatically\n\n### 3. Tag Suggestions\nSuggest relevant tags:\n- Type tags: bug, feature, refactor, docs\n- Priority tags: urgent, important\n- Domain tags: frontend, backend, design, testing (if applicable)\n\nTag consistency rules:\n- list_tags first, then prefer reusing existing tags in that project\n- If no suitable tag exists, create_tag first (color optional, system can auto-generate) and then use the returned tag ID\n- create_task.tags must contain tag IDs only (not tag names)\n\n### 4. Create Task\nUse create_task to create the task immediately — no confirmation needed.\nBefore create_task:\n1. Call list_tags(projectId)\n2. Match suggested tags to existing tags by name (case-insensitive)\n3. For missing tags, call create_tag(projectId, name, color?)\n4. Build create_task.tags from tag IDs only\n\n### 5. Status\nAfter creating, if work starts immediately, use update_task to set status to in-progress.\n\n## Example:\n\n**Input**: \"User reported login page doesn't display correctly on mobile\"\n\n**Output**:\n- Title: Fix login page mobile responsiveness issue\n- Description: User reported the login page displays abnormally on mobile devices, need to check responsive layout.\n- Type: Bug\n- Priority: High (affects user experience)\n- Suggested Tags: bug, frontend, mobile\n- create_task.tags: [existing_or_new_tag_ids]\n- Recommended Project: [Recommend if there's a web project]\n\n## Current Idea:\n\nIdea: \"${idea}\"\n\nAnalyze the idea, select the best matching project, and immediately execute create_task — no confirmation needed.`,\n },\n },\n ],\n };\n}\n\n/**\n * Open Web UI\n * Launch the web visualization interface\n */\nexport function getOpenWebUIPrompt(port?: string): GetPromptResult {\n const portNum = port ? parseInt(port, 10) : 7860;\n return {\n description: 'Open Web Visualization Interface',\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `**[Non-intrusive task]** Pause your current work briefly to complete this quick action, then let the user know it's done and resume what you were doing.\n\nCall the open_web_interface tool${port ? ` with port ${portNum}` : ''} to launch the roadmap-skill web visualization interface.`,\n },\n },\n ],\n };\n}\n\n/**\n * Get Prompt by name\n */\nexport function getPromptByName(name: string, args?: Record<string, string>): GetPromptResult | null {\n switch (name) {\n case 'suggest-tasks':\n return getRecommendNextTasksPrompt(args?.projectId, args?.limit);\n case 'auto-prioritize':\n return getAutoPrioritizePrompt(args?.projectId);\n case 'add-task-details':\n return getEnhanceTaskDetailsPrompt(args?.taskId || '');\n case 'quick-capture':\n return getQuickCapturePrompt(args?.idea || '', args?.projectId);\n case 'open-web-ui':\n return getOpenWebUIPrompt(args?.port);\n default:\n return null;\n }\n}\n\n/**\n * Get all available Prompts\n */\nexport function getAllPrompts(): Prompt[] {\n return projectPrompts;\n}\n"],"mappings":"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","names":["path","path","fs","z","storage","existingTag","writeJsonFile","z","toTaskSummary","z","z","path","fileURLToPath","__filename","fileURLToPath","__dirname","require","tagService","url","z","path","fs","z","writeJsonFile","createServer"]}
|