@qzoft/check-list 1.0.2 → 1.0.4

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 CHANGED
@@ -44,24 +44,42 @@ registerAppResource(server, 'Task Checklist', uiResourceUri, { description: 'Int
44
44
  }],
45
45
  }));
46
46
  registerAppTool(server, 'list_tasks', {
47
- description: 'Discover and display checklists from all markdown files in the project',
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. "show my tasks in now.md"), pass the filename as the `file` parameter. When no file is specified, all markdown files are scanned.',
48
+ inputSchema: {
49
+ file: z.string().optional().describe('Optional relative path to a specific markdown file to show tasks from (e.g. "now.md"). Omit to show tasks from all markdown files.'),
50
+ },
48
51
  _meta: { ui: { resourceUri: uiResourceUri } },
49
- }, async () => {
52
+ }, async ({ file }) => {
50
53
  let mdFiles;
51
- try {
52
- mdFiles = await discoverMarkdownFiles(projectDir);
54
+ if (file) {
55
+ // Single-file mode: resolve and validate the path
56
+ const resolved = path.resolve(projectDir, file);
57
+ const normalizedProject = path.resolve(projectDir);
58
+ if (!resolved.startsWith(normalizedProject + path.sep) && resolved !== normalizedProject) {
59
+ return {
60
+ isError: true,
61
+ content: [{ type: 'text', text: `Invalid file path: ${file}` }],
62
+ };
63
+ }
64
+ mdFiles = [resolved];
53
65
  }
54
- catch (err) {
55
- const message = err instanceof Error ? err.message : String(err);
56
- return {
57
- isError: true,
58
- content: [
59
- {
60
- type: 'text',
61
- text: `Error scanning project directory ${projectDir}: ${message}`,
62
- },
63
- ],
64
- };
66
+ else {
67
+ // All-files mode: discover every markdown file in the project
68
+ try {
69
+ mdFiles = await discoverMarkdownFiles(projectDir);
70
+ }
71
+ catch (err) {
72
+ const message = err instanceof Error ? err.message : String(err);
73
+ return {
74
+ isError: true,
75
+ content: [
76
+ {
77
+ type: 'text',
78
+ text: `Error scanning project directory ${projectDir}: ${message}`,
79
+ },
80
+ ],
81
+ };
82
+ }
65
83
  }
66
84
  const fileGroups = [];
67
85
  for (const filePath of mdFiles) {
@@ -70,6 +88,12 @@ registerAppTool(server, 'list_tasks', {
70
88
  content = await readTaskFile(filePath);
71
89
  }
72
90
  catch {
91
+ if (file) {
92
+ return {
93
+ isError: true,
94
+ content: [{ type: 'text', text: `Could not read file: ${file}` }],
95
+ };
96
+ }
73
97
  continue; // skip files we can't read
74
98
  }
75
99
  const sections = parseTasks(content);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzoft/check-list",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "MCP App for interactive task management from markdown files",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",
@@ -214,8 +214,22 @@
214
214
  }
215
215
  });
216
216
 
217
+ function escapeHtml(str) {
218
+ const div = document.createElement('div');
219
+ div.textContent = str;
220
+ return div.innerHTML;
221
+ }
222
+
217
223
  function handleToolResult(result) {
218
224
  try {
225
+ // Check for error responses first
226
+ if (result.isError) {
227
+ const textContent = result.content?.find(c => c.type === 'text');
228
+ const msg = textContent?.text || 'Unknown error';
229
+ sectionsEl.innerHTML = '<p style="color:var(--save-err)">Error: ' + escapeHtml(msg) + '</p>';
230
+ return;
231
+ }
232
+
219
233
  // Prefer structuredContent, fall back to parsing text content
220
234
  let fileGroups = result.structuredContent?.files;
221
235
  if (!fileGroups) {
@@ -228,7 +242,7 @@
228
242
  renderFileGroups(fileGroups);
229
243
  }
230
244
  } catch (err) {
231
- sectionsEl.innerHTML = '<p>Error loading tasks: ' + (err.message || String(err)) + '</p>';
245
+ sectionsEl.innerHTML = '<p style="color:var(--save-err)">Error loading tasks: ' + escapeHtml(err.message || String(err)) + '</p>';
232
246
  }
233
247
  }
234
248