@j0hanz/todokit-mcp 1.0.1 → 1.0.3
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 +309 -28
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -18
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +14 -29
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/resolve.d.ts +52 -0
- package/dist/lib/resolve.d.ts.map +1 -0
- package/dist/lib/resolve.js +13 -12
- package/dist/lib/resolve.js.map +1 -1
- package/dist/lib/storage.d.ts +10 -1
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +11 -259
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/storage_filters.d.ts.map +1 -1
- package/dist/lib/storage_filters.js +0 -4
- package/dist/lib/storage_filters.js.map +1 -1
- package/dist/lib/storage_mutations.d.ts +11 -0
- package/dist/lib/storage_mutations.d.ts.map +1 -0
- package/dist/lib/storage_mutations.js +66 -0
- package/dist/lib/storage_mutations.js.map +1 -0
- package/dist/lib/storage_state.d.ts +6 -0
- package/dist/lib/storage_state.d.ts.map +1 -0
- package/dist/lib/storage_state.js +161 -0
- package/dist/lib/storage_state.js.map +1 -0
- package/dist/lib/types.d.ts +2 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +4 -4
- package/dist/lib/types.js.map +1 -1
- package/dist/schemas/inputs.d.ts +47 -3
- package/dist/schemas/inputs.d.ts.map +1 -1
- package/dist/schemas/inputs.js.map +1 -1
- package/dist/schemas/iso_date.d.ts +4 -0
- package/dist/schemas/iso_date.d.ts.map +1 -0
- package/dist/schemas/iso_date.js +1 -0
- package/dist/schemas/iso_date.js.map +1 -1
- package/dist/tools/add_todo.d.ts.map +1 -1
- package/dist/tools/add_todo.js +2 -3
- package/dist/tools/add_todo.js.map +1 -1
- package/dist/tools/add_todos.d.ts.map +1 -1
- package/dist/tools/add_todos.js +2 -3
- package/dist/tools/add_todos.js.map +1 -1
- package/dist/tools/complete_todo.d.ts.map +1 -1
- package/dist/tools/complete_todo.js +20 -28
- 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 +8 -28
- 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 +4 -9
- 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 +24 -12
- package/dist/tools/update_todo.js.map +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,61 +1,342 @@
|
|
|
1
|
-
#
|
|
1
|
+
# todokit-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="docs/logo.png" alt="Todokit MCP Server Logo" width="150">
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
An MCP server for Todokit, a task management and productivity tool with JSON storage.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@j0hanz/todokit-mcp)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](package.json)
|
|
6
10
|
|
|
7
|
-
-
|
|
8
|
-
- List todos
|
|
9
|
-
- Complete todos
|
|
10
|
-
- Delete todos
|
|
11
|
-
- Persists data to `todos.json`
|
|
11
|
+
## One-Click Install
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=todokit&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ftodokit-mcp%40latest%22%5D%7D)[](https://insiders.vscode.dev/redirect/mcp/install?name=todokit&inputs=%5B%5D&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40j0hanz%2Ftodokit-mcp%40latest%22%5D%7D&quality=insiders)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
[](https://cursor.com/install-mcp?name=todokit&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBqMGhhbnovdG9kb2tpdC1tY3BAbGF0ZXN0Il19)
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Task management: add, update, complete/reopen, and delete todos.
|
|
20
|
+
- Batch operations: add multiple todos in one call.
|
|
21
|
+
- Rich filtering: status, priority, tags, due dates, and free-text search.
|
|
22
|
+
- Tagging: tags are normalized (trimmed, lowercase, unique) and can be added or removed.
|
|
23
|
+
- Safe deletion: dry-run delete returns previews for ambiguous matches.
|
|
24
|
+
- JSON persistence with queued writes and atomic file writes.
|
|
25
|
+
- List summaries with counts (pending, completed, overdue).
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
16
28
|
|
|
17
29
|
```bash
|
|
18
|
-
|
|
19
|
-
npm run build
|
|
30
|
+
npx -y @j0hanz/todokit-mcp@latest
|
|
20
31
|
```
|
|
21
32
|
|
|
22
|
-
|
|
33
|
+
The server runs over stdio (no HTTP endpoint) and registers MCP tools on startup.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### NPX (recommended)
|
|
23
38
|
|
|
24
39
|
```bash
|
|
25
|
-
|
|
26
|
-
npm run type-check
|
|
27
|
-
npm run test
|
|
28
|
-
npm run test:coverage
|
|
29
|
-
npm run dup-check
|
|
30
|
-
npm run bench
|
|
40
|
+
npx -y @j0hanz/todokit-mcp@latest
|
|
31
41
|
```
|
|
32
42
|
|
|
33
|
-
###
|
|
43
|
+
### Global install
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
```bash
|
|
46
|
+
npm install -g @j0hanz/todokit-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then run:
|
|
37
50
|
|
|
38
51
|
```bash
|
|
39
|
-
|
|
52
|
+
todokit-mcp
|
|
40
53
|
```
|
|
41
54
|
|
|
42
|
-
###
|
|
55
|
+
### From source
|
|
43
56
|
|
|
44
57
|
```bash
|
|
58
|
+
git clone https://github.com/j0hanz/todokit-mcp-server.git
|
|
59
|
+
cd todokit-mcp-server
|
|
60
|
+
npm install
|
|
61
|
+
npm run build
|
|
45
62
|
npm start
|
|
46
63
|
```
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### Storage path
|
|
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.
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# macOS/Linux
|
|
75
|
+
TODOKIT_TODO_FILE=/path/to/todos.json npx -y @j0hanz/todokit-mcp@latest
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```powershell
|
|
79
|
+
# Windows PowerShell
|
|
80
|
+
$env:TODOKIT_TODO_FILE = 'C:\path\to\todos.json'
|
|
81
|
+
npx -y @j0hanz/todokit-mcp@latest
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Tools
|
|
85
|
+
|
|
86
|
+
All tools return a JSON payload in both `content` (stringified) and `structuredContent`.
|
|
87
|
+
|
|
88
|
+
Success payload:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"ok": true,
|
|
93
|
+
"result": {}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Error payload:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"ok": false,
|
|
102
|
+
"error": { "code": "E_CODE", "message": "Details" }
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `result` shape is tool-specific. If a `query` matches multiple todos, tools return `E_AMBIGUOUS` with preview matches and a hint to use an exact `id`.
|
|
107
|
+
|
|
108
|
+
### add_todo
|
|
109
|
+
|
|
110
|
+
Add a new todo item.
|
|
111
|
+
|
|
112
|
+
| Parameter | Type | Required | Default | Description |
|
|
113
|
+
| :---------- | :----- | :------- | :------ | :------------------------------------ |
|
|
114
|
+
| title | string | Yes | - | The title of the todo (1-200 chars) |
|
|
115
|
+
| description | string | No | - | Optional description (max 2000 chars) |
|
|
116
|
+
| priority | string | No | normal | Priority level: low, normal, high |
|
|
117
|
+
| dueDate | string | No | - | Due date in ISO format (YYYY-MM-DD) |
|
|
118
|
+
| tags | array | No | - | Array of tags (max 50, 1-50 chars) |
|
|
119
|
+
|
|
120
|
+
Result fields:
|
|
121
|
+
|
|
122
|
+
- `item` (todo)
|
|
123
|
+
- `summary`
|
|
124
|
+
- `nextActions`
|
|
125
|
+
|
|
126
|
+
### add_todos
|
|
127
|
+
|
|
128
|
+
Add multiple todo items in one call.
|
|
129
|
+
|
|
130
|
+
| Parameter | Type | Required | Default | Description |
|
|
131
|
+
| :-------- | :---- | :------- | :------ | :---------------------------------------------------------- |
|
|
132
|
+
| items | array | Yes | - | Array of todo objects (same fields as add_todo, 1-50 items) |
|
|
133
|
+
|
|
134
|
+
Result fields:
|
|
135
|
+
|
|
136
|
+
- `items` (todos)
|
|
137
|
+
- `summary`
|
|
138
|
+
- `nextActions`
|
|
139
|
+
|
|
140
|
+
### list_todos
|
|
141
|
+
|
|
142
|
+
List todos with filtering, search, sorting, and pagination.
|
|
143
|
+
|
|
144
|
+
| Parameter | Type | Required | Default | Description |
|
|
145
|
+
| :-------- | :------ | :------- | :-------- | :------------------------------------------------ |
|
|
146
|
+
| status | string | No | all | Filter by status: pending, completed, all |
|
|
147
|
+
| completed | boolean | No | - | Deprecated; status takes precedence when provided |
|
|
148
|
+
| priority | string | No | - | Filter by priority: low, normal, high |
|
|
149
|
+
| tag | string | No | - | Filter by tag (must contain) |
|
|
150
|
+
| query | string | No | - | Search text in title, description, or tags |
|
|
151
|
+
| dueBefore | string | No | - | Filter todos due before this date (YYYY-MM-DD) |
|
|
152
|
+
| dueAfter | string | No | - | Filter todos due after this date (YYYY-MM-DD) |
|
|
153
|
+
| sortBy | string | No | createdAt | Sort by: dueDate, priority, createdAt, title |
|
|
154
|
+
| order | string | No | asc | Sort order: asc, desc |
|
|
155
|
+
| limit | number | No | 50 | Max number of results (1-200) |
|
|
156
|
+
| offset | number | No | 0 | Number of results to skip (0-10000) |
|
|
157
|
+
|
|
158
|
+
Result fields:
|
|
159
|
+
|
|
160
|
+
- `items` (todos)
|
|
161
|
+
- `summary`
|
|
162
|
+
- `counts` (`total`, `pending`, `completed`, `overdue`)
|
|
163
|
+
- `limit`
|
|
164
|
+
- `offset`
|
|
165
|
+
|
|
166
|
+
### update_todo
|
|
167
|
+
|
|
168
|
+
Update fields on a todo item. Provide either `id` or `query` to identify the todo.
|
|
169
|
+
|
|
170
|
+
| Parameter | Type | Required | Default | Description |
|
|
171
|
+
| :---------- | :------ | :------- | :------ | :--------------------------------------------- |
|
|
172
|
+
| id | string | No | - | The ID of the todo to update |
|
|
173
|
+
| query | string | No | - | Search text to find a single todo to update |
|
|
174
|
+
| title | string | No | - | New title |
|
|
175
|
+
| description | string | No | - | New description |
|
|
176
|
+
| completed | boolean | No | - | Completion status |
|
|
177
|
+
| priority | string | No | - | New priority level |
|
|
178
|
+
| dueDate | string | No | - | New due date (YYYY-MM-DD) |
|
|
179
|
+
| tags | array | No | - | Replace all tags (max 50) |
|
|
180
|
+
| tagOps | object | No | - | Tag modifications to apply (add/remove arrays) |
|
|
181
|
+
| clearFields | array | No | - | Fields to clear: description, dueDate, tags |
|
|
182
|
+
|
|
183
|
+
Notes:
|
|
184
|
+
|
|
185
|
+
- If both `tags` and `tagOps` are provided, `tags` wins and replaces the list.
|
|
186
|
+
- If no updatable fields are provided, the tool returns an error.
|
|
187
|
+
|
|
188
|
+
Result fields:
|
|
189
|
+
|
|
190
|
+
- `item` (todo)
|
|
191
|
+
- `summary`
|
|
192
|
+
- `nextActions`
|
|
193
|
+
|
|
194
|
+
### complete_todo
|
|
195
|
+
|
|
196
|
+
Set completion status for a todo item. Provide either `id` or `query`.
|
|
197
|
+
|
|
198
|
+
| Parameter | Type | Required | Default | Description |
|
|
199
|
+
| :-------- | :------ | :------- | :------ | :-------------------------------- |
|
|
200
|
+
| id | string | No | - | The ID of the todo to complete |
|
|
201
|
+
| query | string | No | - | Search text to find a single todo |
|
|
202
|
+
| completed | boolean | No | true | Set completion status |
|
|
203
|
+
|
|
204
|
+
Result fields:
|
|
205
|
+
|
|
206
|
+
- `item` (todo)
|
|
207
|
+
- `summary` (includes already-complete or reopen messages)
|
|
208
|
+
- `nextActions`
|
|
209
|
+
|
|
210
|
+
### delete_todo
|
|
211
|
+
|
|
212
|
+
Delete a todo item. Provide either `id` or `query`.
|
|
213
|
+
|
|
214
|
+
| Parameter | Type | Required | Default | Description |
|
|
215
|
+
| :-------- | :------ | :------- | :------ | :-------------------------------------- |
|
|
216
|
+
| id | string | No | - | The ID of the todo to delete |
|
|
217
|
+
| query | string | No | - | Search text to find a single todo |
|
|
218
|
+
| dryRun | boolean | No | false | Simulate deletion without changing data |
|
|
219
|
+
|
|
220
|
+
Result fields:
|
|
221
|
+
|
|
222
|
+
- `deletedIds` (array)
|
|
223
|
+
- `summary`
|
|
224
|
+
- `nextActions` (only when not dryRun)
|
|
225
|
+
- `dryRun` (when dryRun is true)
|
|
226
|
+
- `matches`, `totalMatches` (dry-run + multiple matches)
|
|
227
|
+
|
|
228
|
+
## Data Model
|
|
229
|
+
|
|
230
|
+
A todo item has the following shape:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"id": "string",
|
|
235
|
+
"title": "string",
|
|
236
|
+
"description": "string?",
|
|
237
|
+
"completed": false,
|
|
238
|
+
"priority": "low|normal|high",
|
|
239
|
+
"dueDate": "YYYY-MM-DD?",
|
|
240
|
+
"tags": ["string"],
|
|
241
|
+
"createdAt": "ISO timestamp",
|
|
242
|
+
"updatedAt": "ISO timestamp?",
|
|
243
|
+
"completedAt": "ISO timestamp?"
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Client Configuration
|
|
49
248
|
|
|
50
|
-
|
|
249
|
+
<details>
|
|
250
|
+
<summary><b>VS Code</b></summary>
|
|
251
|
+
|
|
252
|
+
Add this to your `mcpServers` configuration in `settings.json`:
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"todokit": {
|
|
257
|
+
"command": "npx",
|
|
258
|
+
"args": ["-y", "@j0hanz/todokit-mcp@latest"]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
</details>
|
|
264
|
+
|
|
265
|
+
<details>
|
|
266
|
+
<summary><b>Claude Desktop</b></summary>
|
|
267
|
+
|
|
268
|
+
Add this to your `claude_desktop_config.json`:
|
|
51
269
|
|
|
52
270
|
```json
|
|
53
271
|
{
|
|
54
272
|
"mcpServers": {
|
|
55
273
|
"todokit": {
|
|
56
|
-
"command": "
|
|
57
|
-
"args": ["
|
|
274
|
+
"command": "npx",
|
|
275
|
+
"args": ["-y", "@j0hanz/todokit-mcp@latest"]
|
|
58
276
|
}
|
|
59
277
|
}
|
|
60
278
|
}
|
|
61
279
|
```
|
|
280
|
+
|
|
281
|
+
</details>
|
|
282
|
+
|
|
283
|
+
<details>
|
|
284
|
+
<summary><b>Cursor</b></summary>
|
|
285
|
+
|
|
286
|
+
1. Go to **Cursor Settings** > **Features** > **MCP**
|
|
287
|
+
2. Click **+ Add New MCP Server**
|
|
288
|
+
3. Name: `todokit`
|
|
289
|
+
4. Type: `command`
|
|
290
|
+
5. Command: `npx -y @j0hanz/todokit-mcp@latest`
|
|
291
|
+
|
|
292
|
+
</details>
|
|
293
|
+
|
|
294
|
+
## Development
|
|
295
|
+
|
|
296
|
+
### Prerequisites
|
|
297
|
+
|
|
298
|
+
- Node.js >= 20.0.0
|
|
299
|
+
|
|
300
|
+
### Scripts
|
|
301
|
+
|
|
302
|
+
| Command | Description |
|
|
303
|
+
| :-------------------- | :---------------------------------------------------- |
|
|
304
|
+
| npm run build | Compile TypeScript to JavaScript |
|
|
305
|
+
| npm run dev | Run server in watch mode for development |
|
|
306
|
+
| npm start | Run the built server |
|
|
307
|
+
| npm run test | Run unit tests (node --test + tsx) |
|
|
308
|
+
| npm run test:coverage | Run unit tests with coverage |
|
|
309
|
+
| npm run lint | Run ESLint |
|
|
310
|
+
| npm run format | Format with Prettier |
|
|
311
|
+
| npm run format:check | Check formatting with Prettier |
|
|
312
|
+
| npm run type-check | Run TypeScript type checking |
|
|
313
|
+
| npm run dup-check | Run duplicate code checks (jscpd) |
|
|
314
|
+
| npm run clean | Remove the dist/ build output |
|
|
315
|
+
| npm run inspector | Launch the MCP inspector (pass server cmd after `--`) |
|
|
316
|
+
|
|
317
|
+
### Manual verification
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
npm run build
|
|
321
|
+
npm run inspector -- node dist/index.js
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Project structure
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
src/
|
|
328
|
+
index.ts # MCP server entrypoint (stdio)
|
|
329
|
+
tools/ # Tool registrations
|
|
330
|
+
schemas/ # Zod input/output schemas
|
|
331
|
+
lib/ # Storage, matching, shared helpers
|
|
332
|
+
tests/ # Unit tests
|
|
333
|
+
docs/ # Assets (logo)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Contributing
|
|
337
|
+
|
|
338
|
+
Contributions are welcome. Please run `npm run format`, `npm run lint`, `npm run type-check`, and `npm run build` before opening a PR.
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export declare function createServer(): McpServer;
|
|
3
|
+
export declare function shutdown(signal: NodeJS.Signals): Promise<void>;
|
|
4
|
+
export declare function startServer(): Promise<void>;
|
|
2
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE,wBAAgB,YAAY,IAAI,SAAS,CAWxC;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBpE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,50 @@
|
|
|
1
|
+
import { pathToFileURL } from 'node:url';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import packageJson from '../package.json' with { type: 'json' };
|
|
3
5
|
import { registerAllTools } from './tools/index.js';
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const SERVER_VERSION = packageJson.version;
|
|
7
|
+
let shuttingDown = false;
|
|
8
|
+
let activeServer = null;
|
|
9
|
+
export function createServer() {
|
|
10
|
+
const server = new McpServer({ name: 'todokit', version: SERVER_VERSION }, {
|
|
11
|
+
instructions: 'Todokit to-do list manager',
|
|
12
|
+
capabilities: { logging: {} },
|
|
13
|
+
});
|
|
14
|
+
registerAllTools(server);
|
|
15
|
+
return server;
|
|
16
|
+
}
|
|
17
|
+
export async function shutdown(signal) {
|
|
18
|
+
if (shuttingDown) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!activeServer) {
|
|
22
|
+
process.exitCode = 0;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
shuttingDown = true;
|
|
10
26
|
try {
|
|
11
|
-
await
|
|
27
|
+
await activeServer.close();
|
|
12
28
|
}
|
|
13
29
|
catch (error) {
|
|
14
30
|
console.error(`Shutdown error (${signal}):`, error);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
15
33
|
}
|
|
16
|
-
|
|
17
|
-
process.exit(0);
|
|
18
|
-
}
|
|
34
|
+
process.exitCode = 0;
|
|
19
35
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
async function main() {
|
|
36
|
+
export async function startServer() {
|
|
37
|
+
activeServer = createServer();
|
|
23
38
|
const transport = new StdioServerTransport();
|
|
24
|
-
await
|
|
39
|
+
await activeServer.connect(transport);
|
|
40
|
+
}
|
|
41
|
+
const entrypoint = process.argv[1];
|
|
42
|
+
if (entrypoint && import.meta.url === pathToFileURL(entrypoint).href) {
|
|
43
|
+
process.once('SIGINT', shutdown);
|
|
44
|
+
process.once('SIGTERM', shutdown);
|
|
45
|
+
startServer().catch((error) => {
|
|
46
|
+
console.error('Server error:', error);
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
});
|
|
25
49
|
}
|
|
26
|
-
main().catch((error) => {
|
|
27
|
-
console.error('Server error:', error);
|
|
28
|
-
process.exit(1);
|
|
29
|
-
});
|
|
30
50
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC;AAE3C,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;QACjB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,YAAY,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,mBAAmB,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,YAAY,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAElC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACrC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACtC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
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,33 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (typeof error === 'string' && error.length > 0) {
|
|
9
|
-
return error;
|
|
10
|
-
}
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
13
|
-
function isNonEmptyString(value) {
|
|
14
|
-
return typeof value === 'string' && value.length > 0;
|
|
15
|
-
}
|
|
16
|
-
function isObjectWithMessage(value) {
|
|
17
|
-
return typeof value === 'object' && value !== null && 'message' in value;
|
|
18
|
-
}
|
|
19
|
-
function getMessageFromObject(error) {
|
|
20
|
-
if (!isObjectWithMessage(error)) {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
const message = error.message;
|
|
24
|
-
return isNonEmptyString(message) ? message : undefined;
|
|
25
|
-
}
|
|
1
|
+
const MESSAGE_GETTERS = [
|
|
2
|
+
(error) => (error instanceof Error ? error.message : undefined),
|
|
3
|
+
(error) => (typeof error === 'string' ? error : undefined),
|
|
4
|
+
(error) => error && typeof error === 'object' && 'message' in error
|
|
5
|
+
? error.message
|
|
6
|
+
: undefined,
|
|
7
|
+
];
|
|
26
8
|
export function getErrorMessage(error) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
9
|
+
for (const getter of MESSAGE_GETTERS) {
|
|
10
|
+
const message = getter(error);
|
|
11
|
+
if (typeof message === 'string' && message.length > 0) {
|
|
12
|
+
return message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return 'Unknown error';
|
|
31
16
|
}
|
|
32
17
|
export function createErrorResponse(code, message, result) {
|
|
33
18
|
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":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAaA,MAAM,eAAe,GAAoB;IACvC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1D,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK;QACtD,CAAC,CAAE,KAA+B,CAAC,OAAO;QAC1C,CAAC,CAAC,SAAS;CAChB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ErrorResponse } from './errors.js';
|
|
2
|
+
import type { Todo } from './types.js';
|
|
3
|
+
export interface TodoMatchPreview {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
priority: Todo['priority'];
|
|
7
|
+
dueDate?: string;
|
|
8
|
+
completed: boolean;
|
|
9
|
+
}
|
|
10
|
+
export type ResolveTodoInput = {
|
|
11
|
+
id: string;
|
|
12
|
+
query?: never;
|
|
13
|
+
} | {
|
|
14
|
+
query: string;
|
|
15
|
+
id?: never;
|
|
16
|
+
};
|
|
17
|
+
export declare function toResolveInput(input: {
|
|
18
|
+
id?: string;
|
|
19
|
+
query?: string;
|
|
20
|
+
}): ResolveTodoInput;
|
|
21
|
+
export type ResolveTodoResult = {
|
|
22
|
+
kind: 'match';
|
|
23
|
+
todo: Todo;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'missing';
|
|
26
|
+
response: ErrorResponse;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'not_found';
|
|
29
|
+
response: ErrorResponse;
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'ambiguous';
|
|
32
|
+
response: ErrorResponse;
|
|
33
|
+
matches: Todo[];
|
|
34
|
+
previews: TodoMatchPreview[];
|
|
35
|
+
query: string;
|
|
36
|
+
};
|
|
37
|
+
export type MatchOutcome = {
|
|
38
|
+
kind: 'match';
|
|
39
|
+
todo: Todo;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'ambiguous';
|
|
42
|
+
response: ErrorResponse;
|
|
43
|
+
matches: Todo[];
|
|
44
|
+
previews: TodoMatchPreview[];
|
|
45
|
+
query: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'error';
|
|
48
|
+
response: ErrorResponse;
|
|
49
|
+
};
|
|
50
|
+
export declare function unwrapResolution(result: ResolveTodoResult): MatchOutcome;
|
|
51
|
+
export declare function resolveTodoTargetFromTodos(todos: Todo[], input: ResolveTodoInput): ResolveTodoResult;
|
|
52
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAiBD,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAElC,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,gBAAgB,CAQnB;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC9C;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC7B;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC;AAE/C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,YAAY,CAQxE;AAuED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,IAAI,EAAE,EACb,KAAK,EAAE,gBAAgB,GACtB,iBAAiB,CAKnB"}
|
package/dist/lib/resolve.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { createErrorResponse } from './errors.js';
|
|
2
2
|
import { filterTodos } from './storage_filters.js';
|
|
3
3
|
const PREVIEW_LIMIT = 5;
|
|
4
|
-
function
|
|
5
|
-
return {
|
|
4
|
+
function buildMatchPreviews(todos, limit = PREVIEW_LIMIT) {
|
|
5
|
+
return todos.slice(0, limit).map((todo) => ({
|
|
6
6
|
id: todo.id,
|
|
7
7
|
title: todo.title,
|
|
8
8
|
priority: todo.priority,
|
|
9
9
|
dueDate: todo.dueDate,
|
|
10
10
|
completed: todo.completed,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
function buildMatchPreviews(todos, limit = PREVIEW_LIMIT) {
|
|
14
|
-
return todos.slice(0, limit).map(buildMatchPreview);
|
|
11
|
+
}));
|
|
15
12
|
}
|
|
16
13
|
export function toResolveInput(input) {
|
|
17
14
|
if (input.id) {
|
|
@@ -55,23 +52,27 @@ function resolveByIdFromTodos(todos, id) {
|
|
|
55
52
|
}
|
|
56
53
|
function resolveByQueryFromTodos(todos, query) {
|
|
57
54
|
const trimmedQuery = query.trim();
|
|
58
|
-
if (
|
|
55
|
+
if (trimmedQuery.length === 0) {
|
|
59
56
|
return { kind: 'missing', response: createMissingIdentifierError() };
|
|
60
57
|
}
|
|
61
58
|
const matches = filterTodos(todos, { query: trimmedQuery });
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
return resolveQueryMatches(trimmedQuery, matches);
|
|
60
|
+
}
|
|
61
|
+
function resolveQueryMatches(query, matches) {
|
|
62
|
+
const [firstMatch] = matches;
|
|
63
|
+
if (matches.length === 1 && firstMatch) {
|
|
64
|
+
return { kind: 'match', todo: firstMatch };
|
|
64
65
|
}
|
|
65
66
|
if (matches.length === 0) {
|
|
66
|
-
return { kind: 'not_found', response: createNotFoundError(
|
|
67
|
+
return { kind: 'not_found', response: createNotFoundError(query) };
|
|
67
68
|
}
|
|
68
|
-
const { response, previews } = createAmbiguousError(
|
|
69
|
+
const { response, previews } = createAmbiguousError(query, matches);
|
|
69
70
|
return {
|
|
70
71
|
kind: 'ambiguous',
|
|
71
72
|
response,
|
|
72
73
|
matches,
|
|
73
74
|
previews,
|
|
74
|
-
query
|
|
75
|
+
query,
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
export function resolveTodoTargetFromTodos(todos, 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,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"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"}
|