@j0hanz/todokit-mcp 1.0.6 → 1.0.7
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 +48 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/db.d.ts +8 -0
- package/dist/lib/db.d.ts.map +1 -0
- package/dist/lib/db.js +177 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +16 -16
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/resolve.js +1 -1
- package/dist/lib/resolve.js.map +1 -1
- package/dist/lib/storage.d.ts +6 -6
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +143 -82
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/storage_filters.d.ts +6 -6
- package/dist/lib/storage_filters.d.ts.map +1 -1
- package/dist/lib/storage_filters.js +20 -27
- package/dist/lib/storage_filters.js.map +1 -1
- package/dist/lib/storage_mutations.d.ts +8 -3
- package/dist/lib/storage_mutations.d.ts.map +1 -1
- package/dist/lib/storage_mutations.js +0 -68
- package/dist/lib/storage_mutations.js.map +1 -1
- package/dist/tools/complete_todo.d.ts.map +1 -1
- package/dist/tools/complete_todo.js +2 -1
- package/dist/tools/complete_todo.js.map +1 -1
- package/dist/tools/delete_todo.d.ts.map +1 -1
- package/dist/tools/delete_todo.js +4 -2
- package/dist/tools/delete_todo.js.map +1 -1
- package/dist/tools/list_todos.d.ts.map +1 -1
- package/dist/tools/list_todos.js +56 -40
- package/dist/tools/list_todos.js.map +1 -1
- package/dist/tools/update_todo.d.ts.map +1 -1
- package/dist/tools/update_todo.js +55 -50
- package/dist/tools/update_todo.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,12 +17,12 @@ An MCP server for Todokit, a task management and productivity tool with JSON sto
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
19
|
- Task management: add, update, complete/reopen, and delete todos.
|
|
20
|
-
- Batch operations: add multiple todos
|
|
20
|
+
- Batch operations: add multiple todos and bulk delete with filters.
|
|
21
21
|
- Rich filtering: status, priority, tags, due dates, and free-text search.
|
|
22
22
|
- Tagging: tags are normalized (trimmed, lowercase, unique) and can be added or removed.
|
|
23
|
-
- Safe deletion: dry-run delete
|
|
23
|
+
- Safe deletion: dry-run previews before deleting; bulk delete defaults to a safety limit.
|
|
24
24
|
- JSON persistence with queued writes and atomic file writes.
|
|
25
|
-
- List summaries with counts (pending, completed, overdue).
|
|
25
|
+
- List summaries with counts (pending, completed, overdue) and pagination metadata.
|
|
26
26
|
|
|
27
27
|
## Quick Start
|
|
28
28
|
|
|
@@ -66,7 +66,7 @@ npm start
|
|
|
66
66
|
|
|
67
67
|
### Storage path
|
|
68
68
|
|
|
69
|
-
By default, todos are stored in `todos.json` next to the server package (the project root when running from source). To control where data is written, set the `TODOKIT_TODO_FILE` environment variable to an absolute or relative path ending with `.json`. The directory is created as needed; if the file does not exist, the server starts with an empty list.
|
|
69
|
+
By default, todos are stored in `todos.json` next to the server package (the project root when running from source). 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.
|
|
70
70
|
|
|
71
71
|
Examples:
|
|
72
72
|
|
|
@@ -84,6 +84,7 @@ npx -y @j0hanz/todokit-mcp@latest
|
|
|
84
84
|
## Tools
|
|
85
85
|
|
|
86
86
|
All tools return a JSON payload in both `content` (stringified) and `structuredContent`.
|
|
87
|
+
Inputs are validated with strict Zod schemas, so unknown fields are rejected.
|
|
87
88
|
|
|
88
89
|
Success payload:
|
|
89
90
|
|
|
@@ -162,6 +163,11 @@ Result fields:
|
|
|
162
163
|
- `counts` (`total`, `pending`, `completed`, `overdue`)
|
|
163
164
|
- `limit`
|
|
164
165
|
- `offset`
|
|
166
|
+
- `hasMore` (true if more results are available after this page)
|
|
167
|
+
|
|
168
|
+
Notes:
|
|
169
|
+
|
|
170
|
+
- Overdue calculations compare `dueDate` against the server's local calendar date (YYYY-MM-DD).
|
|
165
171
|
|
|
166
172
|
### update_todo
|
|
167
173
|
|
|
@@ -225,6 +231,35 @@ Result fields:
|
|
|
225
231
|
- `dryRun` (when dryRun is true)
|
|
226
232
|
- `matches`, `totalMatches` (dry-run + multiple matches)
|
|
227
233
|
|
|
234
|
+
### delete_todos
|
|
235
|
+
|
|
236
|
+
Delete multiple todos matching filters. At least one filter is required; defaults to limit=10 for safety.
|
|
237
|
+
|
|
238
|
+
| Parameter | Type | Required | Default | Description |
|
|
239
|
+
| :-------- | :------ | :------- | :------ | :--------------------------------------------- |
|
|
240
|
+
| status | string | No | - | Filter by status: pending, completed, all |
|
|
241
|
+
| priority | string | No | - | Filter by priority: low, normal, high |
|
|
242
|
+
| tag | string | No | - | Filter by tag |
|
|
243
|
+
| dueBefore | string | No | - | Delete todos due before this date (YYYY-MM-DD) |
|
|
244
|
+
| dueAfter | string | No | - | Delete todos due after this date (YYYY-MM-DD) |
|
|
245
|
+
| query | string | No | - | Search text filter (1-200 chars) |
|
|
246
|
+
| dryRun | boolean | No | false | Preview deletion without removing data |
|
|
247
|
+
| limit | number | No | 10 | Max items to delete (1-100, safety limit) |
|
|
248
|
+
|
|
249
|
+
Notes:
|
|
250
|
+
|
|
251
|
+
- At least one filter (status, priority, tag, dueBefore, dueAfter, query) is required.
|
|
252
|
+
- The default limit of 10 prevents accidental mass deletions.
|
|
253
|
+
|
|
254
|
+
Result fields:
|
|
255
|
+
|
|
256
|
+
- `deletedIds` (array)
|
|
257
|
+
- `summary`
|
|
258
|
+
- `totalMatched`
|
|
259
|
+
- `matches` (dry-run only, array of previews)
|
|
260
|
+
- `dryRun` (when dryRun is true)
|
|
261
|
+
- `nextActions` (only when not dryRun)
|
|
262
|
+
|
|
228
263
|
## Data Model
|
|
229
264
|
|
|
230
265
|
A todo item has the following shape:
|
|
@@ -238,12 +273,17 @@ A todo item has the following shape:
|
|
|
238
273
|
"priority": "low|normal|high",
|
|
239
274
|
"dueDate": "YYYY-MM-DD?",
|
|
240
275
|
"tags": ["string"],
|
|
241
|
-
"createdAt": "ISO timestamp",
|
|
242
|
-
"updatedAt": "ISO timestamp?",
|
|
243
|
-
"completedAt": "ISO timestamp?"
|
|
276
|
+
"createdAt": "ISO timestamp with offset",
|
|
277
|
+
"updatedAt": "ISO timestamp with offset?",
|
|
278
|
+
"completedAt": "ISO timestamp with offset?"
|
|
244
279
|
}
|
|
245
280
|
```
|
|
246
281
|
|
|
282
|
+
Notes:
|
|
283
|
+
|
|
284
|
+
- `dueDate` uses `YYYY-MM-DD` (date only).
|
|
285
|
+
- `createdAt`, `updatedAt`, and `completedAt` are ISO 8601 timestamps with offset (e.g., `2025-02-28T10:30:00Z`).
|
|
286
|
+
|
|
247
287
|
## Client Configuration
|
|
248
288
|
|
|
249
289
|
<details>
|
|
@@ -335,7 +375,7 @@ docs/ # Assets (logo)
|
|
|
335
375
|
|
|
336
376
|
## Contributing
|
|
337
377
|
|
|
338
|
-
Contributions are welcome. Please run `npm run format`, `npm run lint`, `npm run type-check`, and `npm run
|
|
378
|
+
Contributions are welcome. Please run `npm run format`, `npm run lint`, `npm run type-check`, `npm run build`, `npm test`, `npm run test:coverage`, and `npm run dup-check` before opening a PR.
|
|
339
379
|
|
|
340
380
|
## License
|
|
341
381
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,wBAAgB,YAAY,IAAI,SAAS,CAWxC;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBpE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
5
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { closeDb } from './lib/db.js';
|
|
6
7
|
import { registerAllTools } from './tools/index.js';
|
|
7
8
|
const require = createRequire(import.meta.url);
|
|
8
9
|
const packageJson = require('../package.json');
|
|
@@ -18,14 +19,19 @@ export function createServer() {
|
|
|
18
19
|
return server;
|
|
19
20
|
}
|
|
20
21
|
export async function shutdown(signal) {
|
|
21
|
-
if (shuttingDown)
|
|
22
|
+
if (shuttingDown)
|
|
22
23
|
return;
|
|
24
|
+
shuttingDown = true;
|
|
25
|
+
try {
|
|
26
|
+
await closeDb();
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error('Error closing database:', error);
|
|
23
30
|
}
|
|
24
31
|
if (!activeServer) {
|
|
25
32
|
process.exitCode = 0;
|
|
26
33
|
return;
|
|
27
34
|
}
|
|
28
|
-
shuttingDown = true;
|
|
29
35
|
try {
|
|
30
36
|
await activeServer.close();
|
|
31
37
|
}
|
|
@@ -41,6 +47,14 @@ export async function startServer() {
|
|
|
41
47
|
const transport = new StdioServerTransport();
|
|
42
48
|
await activeServer.connect(transport);
|
|
43
49
|
}
|
|
50
|
+
process.on('unhandledRejection', (reason) => {
|
|
51
|
+
console.error('Unhandled rejection:', reason);
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
});
|
|
54
|
+
process.on('uncaughtException', (error) => {
|
|
55
|
+
console.error('Uncaught exception:', error);
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
});
|
|
44
58
|
const entrypoint = process.argv[1];
|
|
45
59
|
if (entrypoint && import.meta.url === pathToFileURL(entrypoint).href) {
|
|
46
60
|
process.once('SIGINT', shutdown);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAyB,CAAC;AACvE,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,IAAI,OAAO,CAAC;AAEtD,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,YAAY,GAAqB,IAAI,CAAC;AAE1C,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,EAC5C;QACE,YAAY,EAAE,4BAA4B;QAC1C,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;KAC9B,CACF,CAAC;IAEF,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAsB;IACnD,IAAI,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Todo } from './types.js';
|
|
2
|
+
export declare function readTodos(): Promise<Todo[]>;
|
|
3
|
+
export declare function withTodos<T>(mutate: (todos: Todo[]) => {
|
|
4
|
+
todos: Todo[];
|
|
5
|
+
result: T;
|
|
6
|
+
}): Promise<T>;
|
|
7
|
+
export declare function closeDb(): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,IAAI,EAAe,MAAM,YAAY,CAAC;AA0KpD,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAUjD;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GACtD,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAI7C"}
|
package/dist/lib/db.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { TodosSchema } from './types.js';
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const DEFAULT_TODO_FILE = join(__dirname, '../../todos.json');
|
|
8
|
+
const IO_TIMEOUT_MS = 10_000;
|
|
9
|
+
const WRITE_TIMEOUT_MS = 30_000;
|
|
10
|
+
let cache = null;
|
|
11
|
+
let writeQueue = Promise.resolve();
|
|
12
|
+
function isNotFoundError(error) {
|
|
13
|
+
return (typeof error === 'object' &&
|
|
14
|
+
error !== null &&
|
|
15
|
+
'code' in error &&
|
|
16
|
+
error.code === 'ENOENT');
|
|
17
|
+
}
|
|
18
|
+
const TRANSIENT_ERROR_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);
|
|
19
|
+
function getErrorCode(error) {
|
|
20
|
+
if (typeof error !== 'object' || error === null)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (!('code' in error))
|
|
23
|
+
return undefined;
|
|
24
|
+
return error.code;
|
|
25
|
+
}
|
|
26
|
+
function isTransientError(error) {
|
|
27
|
+
const code = getErrorCode(error);
|
|
28
|
+
return code !== undefined && TRANSIENT_ERROR_CODES.has(code);
|
|
29
|
+
}
|
|
30
|
+
function isAbortError(error) {
|
|
31
|
+
return error instanceof Error && error.name === 'AbortError';
|
|
32
|
+
}
|
|
33
|
+
function noop() {
|
|
34
|
+
// Intentionally empty
|
|
35
|
+
}
|
|
36
|
+
function getTodoFilePath() {
|
|
37
|
+
const override = process.env.TODOKIT_TODO_FILE?.trim();
|
|
38
|
+
if (override) {
|
|
39
|
+
return resolve(override);
|
|
40
|
+
}
|
|
41
|
+
return DEFAULT_TODO_FILE;
|
|
42
|
+
}
|
|
43
|
+
function enqueueWrite(task) {
|
|
44
|
+
const run = writeQueue.then(task, task);
|
|
45
|
+
writeQueue = run.then(() => undefined, () => undefined);
|
|
46
|
+
return run;
|
|
47
|
+
}
|
|
48
|
+
async function withTimeout(promise, ms, message) {
|
|
49
|
+
let timeoutId;
|
|
50
|
+
const timeout = new Promise((_, reject) => {
|
|
51
|
+
timeoutId = setTimeout(() => {
|
|
52
|
+
const error = new Error(message);
|
|
53
|
+
error.name = 'AbortError';
|
|
54
|
+
reject(error);
|
|
55
|
+
}, ms);
|
|
56
|
+
});
|
|
57
|
+
try {
|
|
58
|
+
return await Promise.race([promise, timeout]);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
if (timeoutId !== undefined)
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function getFileMtime(path) {
|
|
66
|
+
try {
|
|
67
|
+
const stats = await withTimeout(stat(path), IO_TIMEOUT_MS, 'File stat timed out');
|
|
68
|
+
return stats.mtimeMs;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (isNotFoundError(error))
|
|
72
|
+
return null;
|
|
73
|
+
if (isAbortError(error))
|
|
74
|
+
throw error;
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function readFileIfExists(path) {
|
|
79
|
+
try {
|
|
80
|
+
return await readFile(path, {
|
|
81
|
+
encoding: 'utf8',
|
|
82
|
+
signal: AbortSignal.timeout(IO_TIMEOUT_MS),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (isNotFoundError(error))
|
|
87
|
+
return null;
|
|
88
|
+
if (isAbortError(error))
|
|
89
|
+
throw new Error('File read timed out');
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function loadTodos(path) {
|
|
94
|
+
const raw = await readFileIfExists(path);
|
|
95
|
+
if (!raw)
|
|
96
|
+
return [];
|
|
97
|
+
const parsed = JSON.parse(raw);
|
|
98
|
+
const result = TodosSchema.safeParse(parsed);
|
|
99
|
+
if (!result.success) {
|
|
100
|
+
throw new Error('Invalid todo storage format');
|
|
101
|
+
}
|
|
102
|
+
return result.data;
|
|
103
|
+
}
|
|
104
|
+
function delay(ms) {
|
|
105
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
106
|
+
}
|
|
107
|
+
async function tryRename(from, to) {
|
|
108
|
+
try {
|
|
109
|
+
await rename(from, to);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function shouldRetry(error, attempt) {
|
|
117
|
+
return isTransientError(error) && attempt < 2;
|
|
118
|
+
}
|
|
119
|
+
async function renameWithRetry(from, to) {
|
|
120
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
121
|
+
const error = await tryRename(from, to);
|
|
122
|
+
if (!error)
|
|
123
|
+
return;
|
|
124
|
+
if (!shouldRetry(error, attempt))
|
|
125
|
+
throw error;
|
|
126
|
+
await delay(50 * (attempt + 1));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function writeFileAtomic(path, contents) {
|
|
130
|
+
await mkdir(dirname(path), { recursive: true });
|
|
131
|
+
const tempPath = `${path}.${randomUUID()}.tmp`;
|
|
132
|
+
try {
|
|
133
|
+
await writeFile(tempPath, contents, {
|
|
134
|
+
encoding: 'utf8',
|
|
135
|
+
flush: true,
|
|
136
|
+
signal: AbortSignal.timeout(WRITE_TIMEOUT_MS),
|
|
137
|
+
});
|
|
138
|
+
await renameWithRetry(tempPath, path);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
await rm(tempPath, { force: true }).catch(noop);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function saveTodos(path, todos) {
|
|
145
|
+
const payload = `${JSON.stringify(todos, null, 2)}\n`;
|
|
146
|
+
await writeFileAtomic(path, payload);
|
|
147
|
+
cache = { todos, mtimeMs: await getFileMtime(path) };
|
|
148
|
+
}
|
|
149
|
+
export async function readTodos() {
|
|
150
|
+
await writeQueue;
|
|
151
|
+
const path = getTodoFilePath();
|
|
152
|
+
const mtimeMs = await getFileMtime(path);
|
|
153
|
+
if (cache?.mtimeMs === mtimeMs) {
|
|
154
|
+
return cache.todos;
|
|
155
|
+
}
|
|
156
|
+
const todos = await loadTodos(path);
|
|
157
|
+
cache = { todos, mtimeMs };
|
|
158
|
+
return todos;
|
|
159
|
+
}
|
|
160
|
+
export async function withTodos(mutate) {
|
|
161
|
+
return enqueueWrite(async () => {
|
|
162
|
+
const path = getTodoFilePath();
|
|
163
|
+
const current = await loadTodos(path);
|
|
164
|
+
cache = { todos: current, mtimeMs: await getFileMtime(path) };
|
|
165
|
+
const { todos, result } = mutate(current);
|
|
166
|
+
if (todos !== current) {
|
|
167
|
+
await saveTodos(path, todos);
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
export async function closeDb() {
|
|
173
|
+
await writeQueue;
|
|
174
|
+
writeQueue = Promise.resolve();
|
|
175
|
+
cache = null;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,iBAAiB,EAAE;QACjB,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,IAAI,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,iBAAiB,EAAE;QACjB,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,IAAI,CAAC;CACf;AAaD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQtD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,GACf,aAAa,CAWf"}
|
package/dist/lib/errors.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return typeof error === 'string' && error.length > 0 ? error : undefined;
|
|
6
|
-
}
|
|
7
|
-
function hasMessageProp(error) {
|
|
8
|
-
return Boolean(error && typeof error === 'object' && 'message' in error);
|
|
1
|
+
function normalizeMessage(message) {
|
|
2
|
+
if (typeof message !== 'string' || message.length === 0)
|
|
3
|
+
return undefined;
|
|
4
|
+
return message;
|
|
9
5
|
}
|
|
10
|
-
function
|
|
11
|
-
if (!
|
|
6
|
+
function extractMessageObject(error) {
|
|
7
|
+
if (!error || typeof error !== 'object' || !('message' in error))
|
|
12
8
|
return undefined;
|
|
13
|
-
|
|
14
|
-
return typeof msg === 'string' && msg.length > 0 ? msg : undefined;
|
|
9
|
+
return normalizeMessage(error.message);
|
|
15
10
|
}
|
|
16
11
|
export function getErrorMessage(error) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
if (error instanceof Error) {
|
|
13
|
+
const message = normalizeMessage(error.message);
|
|
14
|
+
if (message)
|
|
15
|
+
return message;
|
|
16
|
+
}
|
|
17
|
+
const directMessage = normalizeMessage(error);
|
|
18
|
+
if (directMessage)
|
|
19
|
+
return directMessage;
|
|
20
|
+
return extractMessageObject(error) ?? 'Unknown error';
|
|
21
21
|
}
|
|
22
22
|
export function createErrorResponse(code, message, result) {
|
|
23
23
|
const structured = {
|
package/dist/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAWA,SAAS,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAWA,SAAS,gBAAgB,CAAC,OAAgB;IACxC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;QAC9D,OAAO,SAAS,CAAC;IACnB,OAAO,gBAAgB,CAAE,KAA8B,CAAC,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,MAAM,aAAa,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,OAAO,oBAAoB,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,OAAe,EACf,MAAgB;IAEhB,MAAM,UAAU,GAAuC;QACrD,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;QACxB,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5C,CAAC;IACF,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;QACtE,iBAAiB,EAAE,UAAU;QAC7B,OAAO,EAAE,IAAa;KACvB,CAAC;AACJ,CAAC"}
|
package/dist/lib/resolve.js
CHANGED
|
@@ -6,8 +6,8 @@ function buildMatchPreviews(todos, limit = PREVIEW_LIMIT) {
|
|
|
6
6
|
id: todo.id,
|
|
7
7
|
title: todo.title,
|
|
8
8
|
priority: todo.priority,
|
|
9
|
-
dueDate: todo.dueDate,
|
|
10
9
|
completed: todo.completed,
|
|
10
|
+
...(todo.dueDate === undefined ? {} : { dueDate: todo.dueDate }),
|
|
11
11
|
}));
|
|
12
12
|
}
|
|
13
13
|
export function toResolveInput(input) {
|
package/dist/lib/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAWnD,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,SAAS,kBAAkB,CACzB,KAAa,EACb,QAAgB,aAAa;IAE7B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/storage.d.ts
CHANGED
|
@@ -3,24 +3,24 @@ import { normalizeTags, type TodoFilters } from './storage_filters.js';
|
|
|
3
3
|
import { type CompleteTodoOutcome, type TodoUpdate } from './storage_mutations.js';
|
|
4
4
|
import { type Todo } from './types.js';
|
|
5
5
|
export { normalizeTags };
|
|
6
|
+
export type { CompleteTodoOutcome };
|
|
6
7
|
interface NewTodoInput {
|
|
7
8
|
title: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
priority?: 'low' | 'normal' | 'high';
|
|
10
|
-
dueDate?: string;
|
|
11
|
-
tags?: string[];
|
|
9
|
+
description?: string | undefined;
|
|
10
|
+
priority?: 'low' | 'normal' | 'high' | undefined;
|
|
11
|
+
dueDate?: string | undefined;
|
|
12
|
+
tags?: string[] | undefined;
|
|
12
13
|
}
|
|
13
14
|
export declare function getTodos(filters?: TodoFilters): Promise<Todo[]>;
|
|
14
15
|
export declare function addTodo(title: string, description?: string, priority?: 'low' | 'normal' | 'high', dueDate?: string, tags?: string[]): Promise<Todo>;
|
|
15
16
|
export declare function addTodos(items: NewTodoInput[]): Promise<Todo[]>;
|
|
16
|
-
export declare function updateTodo(id: string, updates:
|
|
17
|
+
export declare function updateTodo(id: string, updates: TodoUpdate): Promise<Todo | null>;
|
|
17
18
|
export declare function deleteTodo(id: string): Promise<boolean>;
|
|
18
19
|
export type UpdateTodoOutcome = MatchOutcome | {
|
|
19
20
|
kind: 'no_updates';
|
|
20
21
|
};
|
|
21
22
|
export declare function updateTodoBySelector(input: ResolveTodoInput, buildUpdates: (todo: Todo) => TodoUpdate | null): Promise<UpdateTodoOutcome>;
|
|
22
23
|
export declare function deleteTodoBySelector(input: ResolveTodoInput): Promise<MatchOutcome>;
|
|
23
|
-
export type { CompleteTodoOutcome };
|
|
24
24
|
export declare function completeTodoBySelector(input: ResolveTodoInput, completed: boolean): Promise<CompleteTodoOutcome>;
|
|
25
25
|
export declare function deleteTodosByIds(ids: string[]): Promise<string[]>;
|
|
26
26
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAGtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,aAAa,EACb,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAC7B;AAsCD,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAGrE;AAED,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,GAAE,KAAK,GAAG,QAAQ,GAAG,MAAiB,EAC9C,OAAO,CAAC,EAAE,MAAM,EAChB,IAAI,GAAE,MAAM,EAAO,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;AAiBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAM/D;AA2CD,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAEtB;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKvD;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC;AAEtE,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,GAAG,IAAI,GAC9C,OAAO,CAAC,iBAAiB,CAAC,CAyB5B;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAwB9B;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAcjE"}
|