@qzoft/check-list 1.0.7 → 1.0.9
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/dist/server.js +32 -14
- package/package.json +3 -2
package/dist/server.js
CHANGED
|
@@ -44,31 +44,49 @@ registerAppResource(server, 'Task Checklist', uiResourceUri, { description: 'Int
|
|
|
44
44
|
}],
|
|
45
45
|
}));
|
|
46
46
|
registerAppTool(server, 'list_tasks', {
|
|
47
|
-
description: 'Discover and display checklists from markdown files in the project. When the user asks to see tasks in a specific file (e.g. "
|
|
47
|
+
description: 'Discover and display checklists from markdown files in the project. When the user asks to see tasks in a specific file, pass its ABSOLUTE file path as the `file` parameter. IMPORTANT: Always use the full absolute path (e.g. "/Users/me/project/tasks.md" or "C:\\Users\\me\\project\\tasks.md"), never a relative or workspace-relative path. When no file is specified, all markdown files in the project directory are scanned.',
|
|
48
48
|
inputSchema: {
|
|
49
|
-
file: z.string().optional().describe('
|
|
49
|
+
file: z.string().optional().describe('ABSOLUTE path to a specific markdown file (e.g. "/Users/me/project/tasks.md" or "C:\\Users\\me\\project\\tasks.md"). Always use the full absolute path from the file reference. Omit to scan all markdown files in the project directory.'),
|
|
50
50
|
},
|
|
51
51
|
_meta: { ui: { resourceUri: uiResourceUri } },
|
|
52
52
|
}, async ({ file }) => {
|
|
53
53
|
let mdFiles;
|
|
54
54
|
if (file) {
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
// Build a list of candidate paths to try, in priority order
|
|
56
|
+
const candidates = [];
|
|
57
|
+
if (path.isAbsolute(file)) {
|
|
58
|
+
candidates.push(path.resolve(file));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// 1. Relative to projectDir
|
|
62
|
+
candidates.push(path.resolve(projectDir, file));
|
|
63
|
+
// 2. Relative to cwd (if different from projectDir)
|
|
64
|
+
const cwd = process.cwd();
|
|
65
|
+
if (cwd !== projectDir) {
|
|
66
|
+
candidates.push(path.resolve(cwd, file));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Find the first candidate that exists on disk
|
|
70
|
+
let resolved = candidates.find(c => fs.existsSync(c));
|
|
71
|
+
// If none found, search by filename/suffix in projectDir
|
|
72
|
+
if (!resolved) {
|
|
59
73
|
const basename = path.basename(file);
|
|
74
|
+
const suffix = file.replace(/\//g, path.sep);
|
|
60
75
|
try {
|
|
61
76
|
const allMd = await discoverMarkdownFiles(projectDir);
|
|
62
|
-
|
|
63
|
-
|| allMd.find(f =>
|
|
64
|
-
if (match) {
|
|
65
|
-
resolved = match;
|
|
66
|
-
}
|
|
77
|
+
resolved = allMd.find(f => f.endsWith(path.sep + suffix))
|
|
78
|
+
|| allMd.find(f => path.basename(f) === basename);
|
|
67
79
|
}
|
|
68
80
|
catch {
|
|
69
|
-
// ignore discovery errors
|
|
81
|
+
// ignore discovery errors
|
|
70
82
|
}
|
|
71
83
|
}
|
|
84
|
+
if (!resolved) {
|
|
85
|
+
return {
|
|
86
|
+
isError: true,
|
|
87
|
+
content: [{ type: 'text', text: `File not found: ${file}\nSearched in: ${candidates.join(', ')}` }],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
72
90
|
mdFiles = [resolved];
|
|
73
91
|
}
|
|
74
92
|
else {
|
|
@@ -99,7 +117,7 @@ registerAppTool(server, 'list_tasks', {
|
|
|
99
117
|
if (file) {
|
|
100
118
|
return {
|
|
101
119
|
isError: true,
|
|
102
|
-
content: [{ type: 'text', text: `Could not read file: ${
|
|
120
|
+
content: [{ type: 'text', text: `Could not read file: ${filePath}` }],
|
|
103
121
|
};
|
|
104
122
|
}
|
|
105
123
|
continue; // skip files we can't read
|
|
@@ -125,7 +143,7 @@ registerAppTool(server, 'list_tasks', {
|
|
|
125
143
|
registerAppTool(server, 'update_tasks', {
|
|
126
144
|
description: 'Update checkbox states in a project markdown file (auto-saved on toggle)',
|
|
127
145
|
inputSchema: {
|
|
128
|
-
file: z.string().describe('
|
|
146
|
+
file: z.string().describe('ABSOLUTE path to the markdown file (e.g. "/Users/me/project/tasks.md"). Always use the full absolute path.'),
|
|
129
147
|
updates: z.array(z.object({
|
|
130
148
|
line: z.number().describe('0-indexed line number in the markdown file'),
|
|
131
149
|
checked: z.boolean().describe('New checked state for the checkbox'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qzoft/check-list",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "MCP App for interactive task management from markdown files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@modelcontextprotocol/ext-apps": "^1.2.0",
|
|
21
|
-
"@modelcontextprotocol/sdk": "^1.27.1"
|
|
21
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
22
|
+
"@qzoft/check-list": "^1.0.7"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@types/node": "^22.0.0",
|