kanban-lite 1.0.9 → 1.0.13
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/cli.js +1015 -407
- package/dist/extension.js +897 -347
- package/dist/mcp-server.js +550 -189
- package/dist/sdk/index.cjs +1223 -0
- package/dist/sdk/index.mjs +1168 -0
- package/dist/sdk/sdk/KanbanSDK.d.ts +39 -21
- package/dist/sdk/sdk/index.d.ts +4 -3
- package/dist/sdk/sdk/migration.d.ts +6 -0
- package/dist/sdk/sdk/types.d.ts +3 -5
- package/dist/sdk/shared/config.d.ts +23 -10
- package/dist/sdk/shared/types.d.ts +18 -4
- package/dist/standalone-webview/index.js +27 -27
- package/dist/standalone-webview/index.js.map +1 -1
- package/dist/standalone-webview/style.css +1 -1
- package/dist/standalone.js +831 -328
- package/dist/webview/index.js +45 -45
- package/dist/webview/index.js.map +1 -1
- package/dist/webview/style.css +1 -1
- package/package.json +4 -3
- package/src/cli/index.ts +217 -95
- package/src/extension/KanbanPanel.ts +49 -22
- package/src/mcp-server/index.ts +138 -62
- package/src/sdk/KanbanSDK.ts +283 -77
- package/src/sdk/__tests__/KanbanSDK.test.ts +5 -5
- package/src/sdk/__tests__/migration.test.ts +269 -0
- package/src/sdk/__tests__/multi-board.test.ts +449 -0
- package/src/sdk/index.ts +4 -3
- package/src/sdk/migration.ts +52 -0
- package/src/sdk/types.ts +3 -6
- package/src/shared/config.ts +144 -22
- package/src/shared/types.ts +14 -5
- package/src/standalone/__tests__/server.integration.test.ts +38 -37
- package/src/standalone/server.ts +239 -21
- package/src/webview/App.tsx +17 -7
- package/src/webview/components/Toolbar.tsx +99 -3
- package/src/webview/store/index.ts +11 -3
- package/.kanban/backlog/1-test1.md +0 -30
- package/.kanban.json +0 -42
package/src/mcp-server/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
|
4
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
5
5
|
import { z } from 'zod'
|
|
6
6
|
import { KanbanSDK } from '../sdk/KanbanSDK'
|
|
7
|
-
import type {
|
|
7
|
+
import type { Priority } from '../shared/types'
|
|
8
8
|
import { readConfig, writeConfig, configToSettings, settingsToConfig } from '../shared/config'
|
|
9
9
|
import { loadWebhooks, createWebhook, deleteWebhook } from '../standalone/webhooks'
|
|
10
10
|
|
|
@@ -60,19 +60,77 @@ async function main(): Promise<void> {
|
|
|
60
60
|
version: '1.0.0',
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
+
// --- Board Management Tools ---
|
|
64
|
+
|
|
65
|
+
server.tool('list_boards', 'List all kanban boards.', {}, async () => {
|
|
66
|
+
const boards = sdk.listBoards()
|
|
67
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify(boards, null, 2) }] }
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
server.tool('create_board', 'Create a new kanban board.', {
|
|
71
|
+
id: z.string().describe('Board ID (used in directory name)'),
|
|
72
|
+
name: z.string().describe('Display name'),
|
|
73
|
+
description: z.string().optional().describe('Board description'),
|
|
74
|
+
columns: z.array(z.object({ id: z.string(), name: z.string(), color: z.string() })).optional().describe('Board columns (defaults to standard columns)'),
|
|
75
|
+
}, async ({ id, name, description, columns }) => {
|
|
76
|
+
try {
|
|
77
|
+
const board = sdk.createBoard(id, name, { description, columns })
|
|
78
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify(board, null, 2) }] }
|
|
79
|
+
} catch (err) {
|
|
80
|
+
return { content: [{ type: 'text' as const, text: String(err) }], isError: true }
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
server.tool('get_board', 'Get details of a specific board.', {
|
|
85
|
+
boardId: z.string().describe('Board ID'),
|
|
86
|
+
}, async ({ boardId }) => {
|
|
87
|
+
try {
|
|
88
|
+
const board = sdk.getBoard(boardId)
|
|
89
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify({ id: boardId, ...board }, null, 2) }] }
|
|
90
|
+
} catch (err) {
|
|
91
|
+
return { content: [{ type: 'text' as const, text: String(err) }], isError: true }
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
server.tool('delete_board', 'Delete an empty kanban board.', {
|
|
96
|
+
boardId: z.string().describe('Board ID to delete'),
|
|
97
|
+
}, async ({ boardId }) => {
|
|
98
|
+
try {
|
|
99
|
+
await sdk.deleteBoard(boardId)
|
|
100
|
+
return { content: [{ type: 'text' as const, text: `Deleted board: ${boardId}` }] }
|
|
101
|
+
} catch (err) {
|
|
102
|
+
return { content: [{ type: 'text' as const, text: String(err) }], isError: true }
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
server.tool('transfer_card', 'Transfer a card from one board to another.', {
|
|
107
|
+
cardId: z.string().describe('Card ID'),
|
|
108
|
+
fromBoard: z.string().describe('Source board ID'),
|
|
109
|
+
toBoard: z.string().describe('Target board ID'),
|
|
110
|
+
targetStatus: z.string().optional().describe('Status in the target board (defaults to board default)'),
|
|
111
|
+
}, async ({ cardId, fromBoard, toBoard, targetStatus }) => {
|
|
112
|
+
try {
|
|
113
|
+
const card = await sdk.transferCard(cardId, fromBoard, toBoard, targetStatus)
|
|
114
|
+
return { content: [{ type: 'text' as const, text: JSON.stringify(card, null, 2) }] }
|
|
115
|
+
} catch (err) {
|
|
116
|
+
return { content: [{ type: 'text' as const, text: String(err) }], isError: true }
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
|
|
63
120
|
// --- Card Tools ---
|
|
64
121
|
|
|
65
122
|
server.tool(
|
|
66
123
|
'list_cards',
|
|
67
124
|
'List all kanban cards. Optionally filter by status, priority, assignee, or label.',
|
|
68
125
|
{
|
|
69
|
-
|
|
126
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
127
|
+
status: z.string().optional().describe('Filter by status'),
|
|
70
128
|
priority: z.enum(['critical', 'high', 'medium', 'low']).optional().describe('Filter by priority'),
|
|
71
129
|
assignee: z.string().optional().describe('Filter by assignee name'),
|
|
72
130
|
label: z.string().optional().describe('Filter by label'),
|
|
73
131
|
},
|
|
74
|
-
async ({ status, priority, assignee, label }) => {
|
|
75
|
-
let cards = await sdk.listCards()
|
|
132
|
+
async ({ boardId, status, priority, assignee, label }) => {
|
|
133
|
+
let cards = await sdk.listCards(undefined, boardId)
|
|
76
134
|
if (status) cards = cards.filter(c => c.status === status)
|
|
77
135
|
if (priority) cards = cards.filter(c => c.priority === priority)
|
|
78
136
|
if (assignee) cards = cards.filter(c => c.assignee === assignee)
|
|
@@ -101,13 +159,14 @@ async function main(): Promise<void> {
|
|
|
101
159
|
'get_card',
|
|
102
160
|
'Get full details of a specific kanban card by ID. Supports partial ID matching.',
|
|
103
161
|
{
|
|
162
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
104
163
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
105
164
|
},
|
|
106
|
-
async ({ cardId }) => {
|
|
107
|
-
let card = await sdk.getCard(cardId)
|
|
165
|
+
async ({ boardId, cardId }) => {
|
|
166
|
+
let card = await sdk.getCard(cardId, boardId)
|
|
108
167
|
if (!card) {
|
|
109
168
|
// Try partial match
|
|
110
|
-
const all = await sdk.listCards()
|
|
169
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
111
170
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
112
171
|
if (matches.length === 1) {
|
|
113
172
|
card = matches[0]
|
|
@@ -137,24 +196,26 @@ async function main(): Promise<void> {
|
|
|
137
196
|
'create_card',
|
|
138
197
|
'Create a new kanban card. Returns the created card.',
|
|
139
198
|
{
|
|
199
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
140
200
|
title: z.string().describe('Card title'),
|
|
141
201
|
body: z.string().optional().describe('Card body/description (markdown)'),
|
|
142
|
-
status: z.
|
|
202
|
+
status: z.string().optional().describe('Initial status (default: backlog)'),
|
|
143
203
|
priority: z.enum(['critical', 'high', 'medium', 'low']).optional().describe('Priority level (default: medium)'),
|
|
144
204
|
assignee: z.string().optional().describe('Assignee name'),
|
|
145
205
|
dueDate: z.string().optional().describe('Due date (ISO format or YYYY-MM-DD)'),
|
|
146
206
|
labels: z.array(z.string()).optional().describe('Labels/tags'),
|
|
147
207
|
},
|
|
148
|
-
async ({ title, body, status, priority, assignee, dueDate, labels }) => {
|
|
208
|
+
async ({ boardId, title, body, status, priority, assignee, dueDate, labels }) => {
|
|
149
209
|
const content = `# ${title}${body ? '\n\n' + body : ''}`
|
|
150
210
|
|
|
151
211
|
const card = await sdk.createCard({
|
|
152
212
|
content,
|
|
153
|
-
status: status
|
|
213
|
+
status: status || undefined,
|
|
154
214
|
priority: priority as Priority | undefined,
|
|
155
215
|
assignee: assignee || null,
|
|
156
216
|
dueDate: dueDate || null,
|
|
157
217
|
labels: labels || [],
|
|
218
|
+
boardId,
|
|
158
219
|
})
|
|
159
220
|
|
|
160
221
|
return {
|
|
@@ -170,20 +231,21 @@ async function main(): Promise<void> {
|
|
|
170
231
|
'update_card',
|
|
171
232
|
'Update fields of an existing kanban card. Only specified fields are changed.',
|
|
172
233
|
{
|
|
234
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
173
235
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
174
|
-
status: z.
|
|
236
|
+
status: z.string().optional().describe('New status'),
|
|
175
237
|
priority: z.enum(['critical', 'high', 'medium', 'low']).optional().describe('New priority'),
|
|
176
238
|
assignee: z.string().optional().describe('New assignee'),
|
|
177
239
|
dueDate: z.string().optional().describe('New due date'),
|
|
178
240
|
labels: z.array(z.string()).optional().describe('New labels (replaces existing)'),
|
|
179
241
|
content: z.string().optional().describe('New markdown content (replaces existing body)'),
|
|
180
242
|
},
|
|
181
|
-
async ({ cardId, status, priority, assignee, dueDate, labels, content }) => {
|
|
243
|
+
async ({ boardId, cardId, status, priority, assignee, dueDate, labels, content }) => {
|
|
182
244
|
// Resolve partial ID
|
|
183
245
|
let resolvedId = cardId
|
|
184
|
-
const card = await sdk.getCard(cardId)
|
|
246
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
185
247
|
if (!card) {
|
|
186
|
-
const all = await sdk.listCards()
|
|
248
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
187
249
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
188
250
|
if (matches.length === 1) {
|
|
189
251
|
resolvedId = matches[0].id
|
|
@@ -208,7 +270,7 @@ async function main(): Promise<void> {
|
|
|
208
270
|
if (labels) updates.labels = labels
|
|
209
271
|
if (content !== undefined) updates.content = content
|
|
210
272
|
|
|
211
|
-
const updated = await sdk.updateCard(resolvedId, updates)
|
|
273
|
+
const updated = await sdk.updateCard(resolvedId, updates, boardId)
|
|
212
274
|
|
|
213
275
|
return {
|
|
214
276
|
content: [{
|
|
@@ -223,15 +285,16 @@ async function main(): Promise<void> {
|
|
|
223
285
|
'move_card',
|
|
224
286
|
'Move a kanban card to a different status column.',
|
|
225
287
|
{
|
|
288
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
226
289
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
227
|
-
status: z.
|
|
290
|
+
status: z.string().describe('Target status column'),
|
|
228
291
|
},
|
|
229
|
-
async ({ cardId, status }) => {
|
|
292
|
+
async ({ boardId, cardId, status }) => {
|
|
230
293
|
// Resolve partial ID
|
|
231
294
|
let resolvedId = cardId
|
|
232
|
-
const card = await sdk.getCard(cardId)
|
|
295
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
233
296
|
if (!card) {
|
|
234
|
-
const all = await sdk.listCards()
|
|
297
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
235
298
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
236
299
|
if (matches.length === 1) {
|
|
237
300
|
resolvedId = matches[0].id
|
|
@@ -248,7 +311,7 @@ async function main(): Promise<void> {
|
|
|
248
311
|
}
|
|
249
312
|
}
|
|
250
313
|
|
|
251
|
-
const updated = await sdk.moveCard(resolvedId, status
|
|
314
|
+
const updated = await sdk.moveCard(resolvedId, status, undefined, boardId)
|
|
252
315
|
|
|
253
316
|
return {
|
|
254
317
|
content: [{
|
|
@@ -263,14 +326,15 @@ async function main(): Promise<void> {
|
|
|
263
326
|
'delete_card',
|
|
264
327
|
'Permanently delete a kanban card.',
|
|
265
328
|
{
|
|
329
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
266
330
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
267
331
|
},
|
|
268
|
-
async ({ cardId }) => {
|
|
332
|
+
async ({ boardId, cardId }) => {
|
|
269
333
|
// Resolve partial ID
|
|
270
334
|
let resolvedId = cardId
|
|
271
|
-
const card = await sdk.getCard(cardId)
|
|
335
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
272
336
|
if (!card) {
|
|
273
|
-
const all = await sdk.listCards()
|
|
337
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
274
338
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
275
339
|
if (matches.length === 1) {
|
|
276
340
|
resolvedId = matches[0].id
|
|
@@ -287,7 +351,7 @@ async function main(): Promise<void> {
|
|
|
287
351
|
}
|
|
288
352
|
}
|
|
289
353
|
|
|
290
|
-
await sdk.deleteCard(resolvedId)
|
|
354
|
+
await sdk.deleteCard(resolvedId, boardId)
|
|
291
355
|
|
|
292
356
|
return {
|
|
293
357
|
content: [{
|
|
@@ -304,13 +368,14 @@ async function main(): Promise<void> {
|
|
|
304
368
|
'list_attachments',
|
|
305
369
|
'List all attachments on a kanban card.',
|
|
306
370
|
{
|
|
371
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
307
372
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
308
373
|
},
|
|
309
|
-
async ({ cardId }) => {
|
|
374
|
+
async ({ boardId, cardId }) => {
|
|
310
375
|
let resolvedId = cardId
|
|
311
|
-
const card = await sdk.getCard(cardId)
|
|
376
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
312
377
|
if (!card) {
|
|
313
|
-
const all = await sdk.listCards()
|
|
378
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
314
379
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
315
380
|
if (matches.length === 1) {
|
|
316
381
|
resolvedId = matches[0].id
|
|
@@ -327,7 +392,7 @@ async function main(): Promise<void> {
|
|
|
327
392
|
}
|
|
328
393
|
}
|
|
329
394
|
|
|
330
|
-
const attachments = await sdk.listAttachments(resolvedId)
|
|
395
|
+
const attachments = await sdk.listAttachments(resolvedId, boardId)
|
|
331
396
|
return {
|
|
332
397
|
content: [{
|
|
333
398
|
type: 'text' as const,
|
|
@@ -341,14 +406,15 @@ async function main(): Promise<void> {
|
|
|
341
406
|
'add_attachment',
|
|
342
407
|
'Add a file attachment to a kanban card. Copies the file to the card directory.',
|
|
343
408
|
{
|
|
409
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
344
410
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
345
411
|
filePath: z.string().describe('Absolute path to the file to attach'),
|
|
346
412
|
},
|
|
347
|
-
async ({ cardId, filePath }) => {
|
|
413
|
+
async ({ boardId, cardId, filePath }) => {
|
|
348
414
|
let resolvedId = cardId
|
|
349
|
-
const card = await sdk.getCard(cardId)
|
|
415
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
350
416
|
if (!card) {
|
|
351
|
-
const all = await sdk.listCards()
|
|
417
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
352
418
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
353
419
|
if (matches.length === 1) {
|
|
354
420
|
resolvedId = matches[0].id
|
|
@@ -365,7 +431,7 @@ async function main(): Promise<void> {
|
|
|
365
431
|
}
|
|
366
432
|
}
|
|
367
433
|
|
|
368
|
-
const updated = await sdk.addAttachment(resolvedId, filePath)
|
|
434
|
+
const updated = await sdk.addAttachment(resolvedId, filePath, boardId)
|
|
369
435
|
return {
|
|
370
436
|
content: [{
|
|
371
437
|
type: 'text' as const,
|
|
@@ -379,14 +445,15 @@ async function main(): Promise<void> {
|
|
|
379
445
|
'remove_attachment',
|
|
380
446
|
'Remove an attachment from a kanban card. Only removes the reference, not the file.',
|
|
381
447
|
{
|
|
448
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
382
449
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
383
450
|
attachment: z.string().describe('Attachment filename to remove'),
|
|
384
451
|
},
|
|
385
|
-
async ({ cardId, attachment }) => {
|
|
452
|
+
async ({ boardId, cardId, attachment }) => {
|
|
386
453
|
let resolvedId = cardId
|
|
387
|
-
const card = await sdk.getCard(cardId)
|
|
454
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
388
455
|
if (!card) {
|
|
389
|
-
const all = await sdk.listCards()
|
|
456
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
390
457
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
391
458
|
if (matches.length === 1) {
|
|
392
459
|
resolvedId = matches[0].id
|
|
@@ -403,7 +470,7 @@ async function main(): Promise<void> {
|
|
|
403
470
|
}
|
|
404
471
|
}
|
|
405
472
|
|
|
406
|
-
const updated = await sdk.removeAttachment(resolvedId, attachment)
|
|
473
|
+
const updated = await sdk.removeAttachment(resolvedId, attachment, boardId)
|
|
407
474
|
return {
|
|
408
475
|
content: [{
|
|
409
476
|
type: 'text' as const,
|
|
@@ -419,13 +486,14 @@ async function main(): Promise<void> {
|
|
|
419
486
|
'list_comments',
|
|
420
487
|
'List all comments on a kanban card.',
|
|
421
488
|
{
|
|
489
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
422
490
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
423
491
|
},
|
|
424
|
-
async ({ cardId }) => {
|
|
492
|
+
async ({ boardId, cardId }) => {
|
|
425
493
|
let resolvedId = cardId
|
|
426
|
-
const card = await sdk.getCard(cardId)
|
|
494
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
427
495
|
if (!card) {
|
|
428
|
-
const all = await sdk.listCards()
|
|
496
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
429
497
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
430
498
|
if (matches.length === 1) {
|
|
431
499
|
resolvedId = matches[0].id
|
|
@@ -442,7 +510,7 @@ async function main(): Promise<void> {
|
|
|
442
510
|
}
|
|
443
511
|
}
|
|
444
512
|
|
|
445
|
-
const comments = await sdk.listComments(resolvedId)
|
|
513
|
+
const comments = await sdk.listComments(resolvedId, boardId)
|
|
446
514
|
return {
|
|
447
515
|
content: [{
|
|
448
516
|
type: 'text' as const,
|
|
@@ -456,15 +524,16 @@ async function main(): Promise<void> {
|
|
|
456
524
|
'add_comment',
|
|
457
525
|
'Add a comment to a kanban card.',
|
|
458
526
|
{
|
|
527
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
459
528
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
460
529
|
author: z.string().describe('Comment author name'),
|
|
461
530
|
content: z.string().describe('Comment text (supports markdown)'),
|
|
462
531
|
},
|
|
463
|
-
async ({ cardId, author, content }) => {
|
|
532
|
+
async ({ boardId, cardId, author, content }) => {
|
|
464
533
|
let resolvedId = cardId
|
|
465
|
-
const card = await sdk.getCard(cardId)
|
|
534
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
466
535
|
if (!card) {
|
|
467
|
-
const all = await sdk.listCards()
|
|
536
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
468
537
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
469
538
|
if (matches.length === 1) {
|
|
470
539
|
resolvedId = matches[0].id
|
|
@@ -481,7 +550,7 @@ async function main(): Promise<void> {
|
|
|
481
550
|
}
|
|
482
551
|
}
|
|
483
552
|
|
|
484
|
-
const updated = await sdk.addComment(resolvedId, author, content)
|
|
553
|
+
const updated = await sdk.addComment(resolvedId, author, content, boardId)
|
|
485
554
|
const added = updated.comments[updated.comments.length - 1]
|
|
486
555
|
return {
|
|
487
556
|
content: [{
|
|
@@ -496,15 +565,16 @@ async function main(): Promise<void> {
|
|
|
496
565
|
'update_comment',
|
|
497
566
|
'Update the content of a comment on a kanban card.',
|
|
498
567
|
{
|
|
568
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
499
569
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
500
570
|
commentId: z.string().describe('Comment ID (e.g. "c1")'),
|
|
501
571
|
content: z.string().describe('New comment text'),
|
|
502
572
|
},
|
|
503
|
-
async ({ cardId, commentId, content }) => {
|
|
573
|
+
async ({ boardId, cardId, commentId, content }) => {
|
|
504
574
|
let resolvedId = cardId
|
|
505
|
-
const card = await sdk.getCard(cardId)
|
|
575
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
506
576
|
if (!card) {
|
|
507
|
-
const all = await sdk.listCards()
|
|
577
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
508
578
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
509
579
|
if (matches.length === 1) {
|
|
510
580
|
resolvedId = matches[0].id
|
|
@@ -522,7 +592,7 @@ async function main(): Promise<void> {
|
|
|
522
592
|
}
|
|
523
593
|
|
|
524
594
|
try {
|
|
525
|
-
const updated = await sdk.updateComment(resolvedId, commentId, content)
|
|
595
|
+
const updated = await sdk.updateComment(resolvedId, commentId, content, boardId)
|
|
526
596
|
const comment = updated.comments.find(c => c.id === commentId)
|
|
527
597
|
return {
|
|
528
598
|
content: [{
|
|
@@ -543,14 +613,15 @@ async function main(): Promise<void> {
|
|
|
543
613
|
'delete_comment',
|
|
544
614
|
'Delete a comment from a kanban card.',
|
|
545
615
|
{
|
|
616
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
546
617
|
cardId: z.string().describe('Card ID (or partial ID)'),
|
|
547
618
|
commentId: z.string().describe('Comment ID (e.g. "c1")'),
|
|
548
619
|
},
|
|
549
|
-
async ({ cardId, commentId }) => {
|
|
620
|
+
async ({ boardId, cardId, commentId }) => {
|
|
550
621
|
let resolvedId = cardId
|
|
551
|
-
const card = await sdk.getCard(cardId)
|
|
622
|
+
const card = await sdk.getCard(cardId, boardId)
|
|
552
623
|
if (!card) {
|
|
553
|
-
const all = await sdk.listCards()
|
|
624
|
+
const all = await sdk.listCards(undefined, boardId)
|
|
554
625
|
const matches = all.filter(c => c.id.includes(cardId))
|
|
555
626
|
if (matches.length === 1) {
|
|
556
627
|
resolvedId = matches[0].id
|
|
@@ -568,7 +639,7 @@ async function main(): Promise<void> {
|
|
|
568
639
|
}
|
|
569
640
|
|
|
570
641
|
try {
|
|
571
|
-
await sdk.deleteComment(resolvedId, commentId)
|
|
642
|
+
await sdk.deleteComment(resolvedId, commentId, boardId)
|
|
572
643
|
return {
|
|
573
644
|
content: [{
|
|
574
645
|
type: 'text' as const,
|
|
@@ -589,9 +660,11 @@ async function main(): Promise<void> {
|
|
|
589
660
|
server.tool(
|
|
590
661
|
'list_columns',
|
|
591
662
|
'List all kanban board columns.',
|
|
592
|
-
{
|
|
593
|
-
|
|
594
|
-
|
|
663
|
+
{
|
|
664
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
665
|
+
},
|
|
666
|
+
async ({ boardId }) => {
|
|
667
|
+
const columns = await sdk.listColumns(boardId)
|
|
595
668
|
return {
|
|
596
669
|
content: [{
|
|
597
670
|
type: 'text' as const,
|
|
@@ -605,12 +678,13 @@ async function main(): Promise<void> {
|
|
|
605
678
|
'add_column',
|
|
606
679
|
'Add a new column to the kanban board.',
|
|
607
680
|
{
|
|
681
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
608
682
|
id: z.string().describe('Unique column ID (used in card status field)'),
|
|
609
683
|
name: z.string().describe('Display name for the column'),
|
|
610
684
|
color: z.string().describe('Column color (hex format, e.g. "#3b82f6")'),
|
|
611
685
|
},
|
|
612
|
-
async ({ id, name, color }) => {
|
|
613
|
-
const columns = await sdk.addColumn({ id, name, color })
|
|
686
|
+
async ({ boardId, id, name, color }) => {
|
|
687
|
+
const columns = await sdk.addColumn({ id, name, color }, boardId)
|
|
614
688
|
return {
|
|
615
689
|
content: [{
|
|
616
690
|
type: 'text' as const,
|
|
@@ -624,15 +698,16 @@ async function main(): Promise<void> {
|
|
|
624
698
|
'update_column',
|
|
625
699
|
'Update an existing kanban board column.',
|
|
626
700
|
{
|
|
701
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
627
702
|
columnId: z.string().describe('Column ID to update'),
|
|
628
703
|
name: z.string().optional().describe('New display name'),
|
|
629
704
|
color: z.string().optional().describe('New color (hex format)'),
|
|
630
705
|
},
|
|
631
|
-
async ({ columnId, name, color }) => {
|
|
706
|
+
async ({ boardId, columnId, name, color }) => {
|
|
632
707
|
const updates: Record<string, string> = {}
|
|
633
708
|
if (name) updates.name = name
|
|
634
709
|
if (color) updates.color = color
|
|
635
|
-
const columns = await sdk.updateColumn(columnId, updates)
|
|
710
|
+
const columns = await sdk.updateColumn(columnId, updates, boardId)
|
|
636
711
|
return {
|
|
637
712
|
content: [{
|
|
638
713
|
type: 'text' as const,
|
|
@@ -646,10 +721,11 @@ async function main(): Promise<void> {
|
|
|
646
721
|
'remove_column',
|
|
647
722
|
'Remove a column from the kanban board. Fails if any cards are in the column.',
|
|
648
723
|
{
|
|
724
|
+
boardId: z.string().optional().describe('Board ID (uses default board if omitted)'),
|
|
649
725
|
columnId: z.string().describe('Column ID to remove'),
|
|
650
726
|
},
|
|
651
|
-
async ({ columnId }) => {
|
|
652
|
-
const columns = await sdk.removeColumn(columnId)
|
|
727
|
+
async ({ boardId, columnId }) => {
|
|
728
|
+
const columns = await sdk.removeColumn(columnId, boardId)
|
|
653
729
|
return {
|
|
654
730
|
content: [{
|
|
655
731
|
type: 'text' as const,
|
|
@@ -690,7 +766,7 @@ async function main(): Promise<void> {
|
|
|
690
766
|
showFileName: z.boolean().optional().describe('Show file name on cards'),
|
|
691
767
|
compactMode: z.boolean().optional().describe('Enable compact card display'),
|
|
692
768
|
defaultPriority: z.enum(['critical', 'high', 'medium', 'low']).optional().describe('Default priority for new cards'),
|
|
693
|
-
defaultStatus: z.
|
|
769
|
+
defaultStatus: z.string().optional().describe('Default status for new cards'),
|
|
694
770
|
},
|
|
695
771
|
async (updates) => {
|
|
696
772
|
const config = readConfig(workspaceRoot)
|