@j0hanz/todokit-mcp 1.2.1 → 1.2.2

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/README.md CHANGED
@@ -66,6 +66,8 @@ npm start
66
66
 
67
67
  By default, todos are stored in `todos.json` in the current working directory. To control where data is written, set the `TODOKIT_TODO_FILE` environment variable to an absolute or relative path ending with `.json`. Relative paths resolve from the current working directory. The directory is created as needed; if the file does not exist, the server starts with an empty list.
68
68
 
69
+ When all todos are completed, the server removes the storage file so it does not linger on disk.
70
+
69
71
  Examples:
70
72
 
71
73
  ```bash
package/dist/storage.js CHANGED
@@ -283,9 +283,33 @@ export async function withTodos(mutate) {
283
283
  if (nextTodos === todos) {
284
284
  return { kind: 'no_change', result };
285
285
  }
286
+ if (areAllTodosCompleted(nextTodos)) {
287
+ return { kind: 'delete_file', result };
288
+ }
286
289
  return { kind: 'save', todos: nextTodos, result };
287
290
  });
288
291
  }
292
+ function areAllTodosCompleted(todos) {
293
+ return todos.length > 0 && todos.every((todo) => todo.completed);
294
+ }
295
+ function normalizeTodoFileUpdate(outcome, current, hasPersistedFile) {
296
+ if (outcome.kind === 'save' && areAllTodosCompleted(outcome.todos)) {
297
+ return {
298
+ kind: 'proceed',
299
+ outcome: { kind: 'delete_file', result: outcome.result },
300
+ };
301
+ }
302
+ if (outcome.kind !== 'no_change') {
303
+ return { kind: 'proceed', outcome };
304
+ }
305
+ if (hasPersistedFile && areAllTodosCompleted(current)) {
306
+ return {
307
+ kind: 'proceed',
308
+ outcome: { kind: 'delete_file', result: outcome.result },
309
+ };
310
+ }
311
+ return { kind: 'return', result: outcome.result };
312
+ }
289
313
  async function deleteTodoFile(path) {
290
314
  const start = nowMs();
291
315
  await withTimeout(rm(path, { force: true }), WRITE_TIMEOUT_MS, 'File remove timed out').catch((error) => {
@@ -311,10 +335,11 @@ async function withTodoFileUpdate(work) {
311
335
  const mtimeMs = await getFileMtime(path, IO_TIMEOUT_MS);
312
336
  const current = cache?.mtimeMs === mtimeMs ? cache.todos : await loadTodos(path);
313
337
  cache = { todos: current, mtimeMs };
314
- const outcome = work(current);
315
- if (outcome.kind === 'no_change') {
316
- return outcome.result;
338
+ const normalized = normalizeTodoFileUpdate(work(current), current, mtimeMs !== null);
339
+ if (normalized.kind === 'return') {
340
+ return normalized.result;
317
341
  }
342
+ const { outcome } = normalized;
318
343
  const release = await acquireWriteLock(path, getLockTimeoutMs());
319
344
  try {
320
345
  const latestMtime = await getFileMtime(path, IO_TIMEOUT_MS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/todokit-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "mcpName": "io.github.j0hanz/todokit",
5
5
  "description": "A MCP server for Todokit, a task management and productivity tool with JSON storage.",
6
6
  "type": "module",