@grec0/memory-bank-mcp 0.0.2 → 0.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 +420 -425
- package/dist/common/chunker.js +515 -3
- package/dist/common/embeddingService.js +51 -39
- package/dist/common/fileScanner.js +48 -29
- package/dist/common/indexManager.js +85 -46
- package/dist/common/logger.js +54 -0
- package/dist/common/vectorStore.js +47 -4
- package/dist/index.js +1 -1
- package/dist/tools/analyzeCoverage.js +66 -46
- package/dist/tools/indexCode.js +1 -0
- package/package.json +2 -1
- package/dist/common/setup.js +0 -49
- package/dist/common/utils.js +0 -215
- package/dist/operations/boardMemberships.js +0 -186
- package/dist/operations/boards.js +0 -268
- package/dist/operations/cards.js +0 -426
- package/dist/operations/comments.js +0 -249
- package/dist/operations/labels.js +0 -258
- package/dist/operations/lists.js +0 -157
- package/dist/operations/projects.js +0 -102
- package/dist/operations/tasks.js +0 -238
- package/dist/tools/board-summary.js +0 -151
- package/dist/tools/card-details.js +0 -106
- package/dist/tools/create-card-with-tasks.js +0 -81
- package/dist/tools/workflow-actions.js +0 -145
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Label operations for the MCP Kanban server
|
|
3
|
-
*
|
|
4
|
-
* This module provides functions for interacting with labels in the Planka Kanban board,
|
|
5
|
-
* including creating, retrieving, updating, and deleting labels, as well as
|
|
6
|
-
* adding and removing labels from cards.
|
|
7
|
-
*/
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
import { plankaRequest } from "../common/utils.js";
|
|
10
|
-
import { PlankaLabelSchema } from "../common/types.js";
|
|
11
|
-
/**
|
|
12
|
-
* Valid color options for labels in Planka
|
|
13
|
-
*/
|
|
14
|
-
export const VALID_LABEL_COLORS = [
|
|
15
|
-
"berry-red",
|
|
16
|
-
"pumpkin-orange",
|
|
17
|
-
"lagoon-blue",
|
|
18
|
-
"pink-tulip",
|
|
19
|
-
"light-mud",
|
|
20
|
-
"orange-peel",
|
|
21
|
-
"bright-moss",
|
|
22
|
-
"antique-blue",
|
|
23
|
-
"dark-granite",
|
|
24
|
-
"lagune-blue",
|
|
25
|
-
"sunny-grass",
|
|
26
|
-
"morning-sky",
|
|
27
|
-
"light-orange",
|
|
28
|
-
"midnight-blue",
|
|
29
|
-
"tank-green",
|
|
30
|
-
"gun-metal",
|
|
31
|
-
"wet-moss",
|
|
32
|
-
"red-burgundy",
|
|
33
|
-
"light-concrete",
|
|
34
|
-
"apricot-red",
|
|
35
|
-
"desert-sand",
|
|
36
|
-
"navy-blue",
|
|
37
|
-
"egg-yellow",
|
|
38
|
-
"coral-green",
|
|
39
|
-
"light-cocoa",
|
|
40
|
-
];
|
|
41
|
-
/**
|
|
42
|
-
* Schema for creating a new label
|
|
43
|
-
* @property {string} boardId - The ID of the board to create the label in
|
|
44
|
-
* @property {string} name - The name of the label
|
|
45
|
-
* @property {string} color - The color of the label (must be one of the valid colors)
|
|
46
|
-
* @property {number} [position] - The position of the label in the board (default: 65535)
|
|
47
|
-
*/
|
|
48
|
-
export const CreateLabelSchema = z.object({
|
|
49
|
-
boardId: z.string().describe("Board ID"),
|
|
50
|
-
name: z.string().describe("Label name"),
|
|
51
|
-
color: z.enum(VALID_LABEL_COLORS).describe("Label color"),
|
|
52
|
-
position: z.number().optional().describe("Label position (default: 65535)"),
|
|
53
|
-
});
|
|
54
|
-
/**
|
|
55
|
-
* Schema for retrieving labels from a board
|
|
56
|
-
* @property {string} boardId - The ID of the board to get labels from
|
|
57
|
-
*/
|
|
58
|
-
export const GetLabelsSchema = z.object({
|
|
59
|
-
boardId: z.string().describe("Board ID"),
|
|
60
|
-
});
|
|
61
|
-
export const GetLabelSchema = z.object({
|
|
62
|
-
id: z.string().describe("Label ID"),
|
|
63
|
-
});
|
|
64
|
-
/**
|
|
65
|
-
* Schema for updating a label
|
|
66
|
-
* @property {string} id - The ID of the label to update
|
|
67
|
-
* @property {string} [name] - The new name for the label
|
|
68
|
-
* @property {string} [color] - The new color for the label
|
|
69
|
-
* @property {number} [position] - The new position for the label
|
|
70
|
-
*/
|
|
71
|
-
export const UpdateLabelSchema = z.object({
|
|
72
|
-
id: z.string().describe("Label ID"),
|
|
73
|
-
name: z.string().optional().describe("Label name"),
|
|
74
|
-
color: z.enum(VALID_LABEL_COLORS).optional().describe("Label color"),
|
|
75
|
-
position: z.number().optional().describe("Label position"),
|
|
76
|
-
});
|
|
77
|
-
/**
|
|
78
|
-
* Schema for deleting a label
|
|
79
|
-
* @property {string} id - The ID of the label to delete
|
|
80
|
-
*/
|
|
81
|
-
export const DeleteLabelSchema = z.object({
|
|
82
|
-
id: z.string().describe("Label ID"),
|
|
83
|
-
});
|
|
84
|
-
/**
|
|
85
|
-
* Schema for adding a label to a card
|
|
86
|
-
* @property {string} cardId - The ID of the card to add the label to
|
|
87
|
-
* @property {string} labelId - The ID of the label to add to the card
|
|
88
|
-
*/
|
|
89
|
-
export const AddLabelToCardSchema = z.object({
|
|
90
|
-
cardId: z.string().describe("Card ID"),
|
|
91
|
-
labelId: z.string().describe("Label ID"),
|
|
92
|
-
});
|
|
93
|
-
/**
|
|
94
|
-
* Schema for removing a label from a card
|
|
95
|
-
* @property {string} cardId - The ID of the card to remove the label from
|
|
96
|
-
* @property {string} labelId - The ID of the label to remove from the card
|
|
97
|
-
*/
|
|
98
|
-
export const RemoveLabelFromCardSchema = z.object({
|
|
99
|
-
cardId: z.string().describe("Card ID"),
|
|
100
|
-
labelId: z.string().describe("Label ID"),
|
|
101
|
-
});
|
|
102
|
-
// Response schemas
|
|
103
|
-
const LabelsResponseSchema = z.object({
|
|
104
|
-
items: z.array(PlankaLabelSchema),
|
|
105
|
-
included: z.record(z.any()).optional(),
|
|
106
|
-
});
|
|
107
|
-
const LabelResponseSchema = z.object({
|
|
108
|
-
item: PlankaLabelSchema,
|
|
109
|
-
included: z.record(z.any()).optional(),
|
|
110
|
-
});
|
|
111
|
-
const CardLabelResponseSchema = z.object({
|
|
112
|
-
item: z.object({
|
|
113
|
-
id: z.string(),
|
|
114
|
-
cardId: z.string(),
|
|
115
|
-
labelId: z.string(),
|
|
116
|
-
createdAt: z.string(),
|
|
117
|
-
updatedAt: z.string().nullable(),
|
|
118
|
-
}),
|
|
119
|
-
included: z.record(z.any()).optional(),
|
|
120
|
-
});
|
|
121
|
-
// Function implementations
|
|
122
|
-
/**
|
|
123
|
-
* Creates a new label in a board
|
|
124
|
-
*
|
|
125
|
-
* @param {CreateLabelOptions} options - Options for creating the label
|
|
126
|
-
* @param {string} options.boardId - The ID of the board to create the label in
|
|
127
|
-
* @param {string} options.name - The name of the label
|
|
128
|
-
* @param {string} options.color - The color of the label
|
|
129
|
-
* @param {number} [options.position] - The position of the label in the board (default: 65535)
|
|
130
|
-
* @returns {Promise<object>} The created label
|
|
131
|
-
* @throws {Error} If the label creation fails
|
|
132
|
-
*/
|
|
133
|
-
export async function createLabel(options) {
|
|
134
|
-
try {
|
|
135
|
-
const response = await plankaRequest(`/api/boards/${options.boardId}/labels`, {
|
|
136
|
-
method: "POST",
|
|
137
|
-
body: {
|
|
138
|
-
name: options.name,
|
|
139
|
-
color: options.color,
|
|
140
|
-
position: options.position,
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
const parsedResponse = LabelResponseSchema.parse(response);
|
|
144
|
-
return parsedResponse.item;
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
throw new Error(`Failed to create label: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Retrieves all labels for a specific board
|
|
152
|
-
*
|
|
153
|
-
* @param {string} boardId - The ID of the board to get labels from
|
|
154
|
-
* @returns {Promise<Array<object>>} Array of labels in the board
|
|
155
|
-
*/
|
|
156
|
-
export async function getLabels(boardId) {
|
|
157
|
-
try {
|
|
158
|
-
// Get the board which includes labels in the response
|
|
159
|
-
const response = await plankaRequest(`/api/boards/${boardId}`);
|
|
160
|
-
// Check if the response has the expected structure
|
|
161
|
-
if (response &&
|
|
162
|
-
typeof response === "object" &&
|
|
163
|
-
"included" in response &&
|
|
164
|
-
response.included &&
|
|
165
|
-
typeof response.included === "object" &&
|
|
166
|
-
"labels" in response.included) {
|
|
167
|
-
// Get the labels from the included property
|
|
168
|
-
const labels = response.included.labels;
|
|
169
|
-
if (Array.isArray(labels)) {
|
|
170
|
-
return labels;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// If we can't find labels in the expected format, return an empty array
|
|
174
|
-
return [];
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
// If all else fails, return an empty array
|
|
178
|
-
return [];
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Updates a label's properties
|
|
183
|
-
*
|
|
184
|
-
* @param {string} id - The ID of the label to update
|
|
185
|
-
* @param {Partial<Omit<CreateLabelOptions, "boardId">>} options - The properties to update
|
|
186
|
-
* @returns {Promise<object>} The updated label
|
|
187
|
-
*/
|
|
188
|
-
export async function updateLabel(id, options) {
|
|
189
|
-
try {
|
|
190
|
-
const response = await plankaRequest(`/api/labels/${id}`, {
|
|
191
|
-
method: "PATCH",
|
|
192
|
-
body: options,
|
|
193
|
-
});
|
|
194
|
-
const parsedResponse = LabelResponseSchema.parse(response);
|
|
195
|
-
return parsedResponse.item;
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
throw new Error(`Failed to update label: ${error instanceof Error ? error.message : String(error)}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Deletes a label by ID
|
|
203
|
-
*
|
|
204
|
-
* @param {string} id - The ID of the label to delete
|
|
205
|
-
* @returns {Promise<{success: boolean}>} Success indicator
|
|
206
|
-
*/
|
|
207
|
-
export async function deleteLabel(id) {
|
|
208
|
-
try {
|
|
209
|
-
await plankaRequest(`/api/labels/${id}`, {
|
|
210
|
-
method: "DELETE",
|
|
211
|
-
});
|
|
212
|
-
return { success: true };
|
|
213
|
-
}
|
|
214
|
-
catch (error) {
|
|
215
|
-
throw new Error(`Failed to delete label: ${error instanceof Error ? error.message : String(error)}`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Adds a label to a card
|
|
220
|
-
*
|
|
221
|
-
* @param {string} cardId - The ID of the card to add the label to
|
|
222
|
-
* @param {string} labelId - The ID of the label to add to the card
|
|
223
|
-
* @returns {Promise<object>} The created card-label relationship
|
|
224
|
-
*/
|
|
225
|
-
export async function addLabelToCard(cardId, labelId) {
|
|
226
|
-
try {
|
|
227
|
-
// The correct endpoint is /api/cards/{cardId}/labels with labelId in the body
|
|
228
|
-
await plankaRequest(`/api/cards/${cardId}/labels`, {
|
|
229
|
-
method: "POST",
|
|
230
|
-
body: {
|
|
231
|
-
labelId,
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
return { success: true };
|
|
235
|
-
}
|
|
236
|
-
catch (error) {
|
|
237
|
-
throw new Error(`Failed to add label to card: ${error instanceof Error ? error.message : String(error)}`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Removes a label from a card
|
|
242
|
-
*
|
|
243
|
-
* @param {string} cardId - The ID of the card to remove the label from
|
|
244
|
-
* @param {string} labelId - The ID of the label to remove from the card
|
|
245
|
-
* @returns {Promise<{success: boolean}>} Success indicator
|
|
246
|
-
*/
|
|
247
|
-
export async function removeLabelFromCard(cardId, labelId) {
|
|
248
|
-
try {
|
|
249
|
-
// The correct endpoint is /api/cards/{cardId}/labels/{labelId}
|
|
250
|
-
await plankaRequest(`/api/cards/${cardId}/labels/${labelId}`, {
|
|
251
|
-
method: "DELETE",
|
|
252
|
-
});
|
|
253
|
-
return { success: true };
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
throw new Error(`Failed to remove label from card: ${error instanceof Error ? error.message : String(error)}`);
|
|
257
|
-
}
|
|
258
|
-
}
|
package/dist/operations/lists.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview List operations for the MCP Kanban server
|
|
3
|
-
*
|
|
4
|
-
* This module provides functions for interacting with lists in the Planka Kanban board,
|
|
5
|
-
* including creating, retrieving, updating, and deleting lists.
|
|
6
|
-
*/
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { plankaRequest } from "../common/utils.js";
|
|
9
|
-
import { PlankaListSchema } from "../common/types.js";
|
|
10
|
-
// Schema definitions
|
|
11
|
-
/**
|
|
12
|
-
* Schema for creating a new list
|
|
13
|
-
* @property {string} boardId - The ID of the board to create the list in
|
|
14
|
-
* @property {string} name - The name of the list
|
|
15
|
-
* @property {number} [position] - The position of the list in the board (default: 65535)
|
|
16
|
-
*/
|
|
17
|
-
export const CreateListSchema = z.object({
|
|
18
|
-
boardId: z.string().describe("Board ID"),
|
|
19
|
-
name: z.string().describe("List name"),
|
|
20
|
-
position: z.number().optional().describe("List position (default: 65535)"),
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Schema for retrieving lists from a board
|
|
24
|
-
* @property {string} boardId - The ID of the board to get lists from
|
|
25
|
-
*/
|
|
26
|
-
export const GetListsSchema = z.object({
|
|
27
|
-
boardId: z.string().describe("Board ID"),
|
|
28
|
-
});
|
|
29
|
-
/**
|
|
30
|
-
* Schema for updating a list
|
|
31
|
-
* @property {string} id - The ID of the list to update
|
|
32
|
-
* @property {string} [name] - The new name for the list
|
|
33
|
-
* @property {number} [position] - The new position for the list
|
|
34
|
-
*/
|
|
35
|
-
export const UpdateListSchema = z.object({
|
|
36
|
-
id: z.string().describe("List ID"),
|
|
37
|
-
name: z.string().optional().describe("List name"),
|
|
38
|
-
position: z.number().optional().describe("List position"),
|
|
39
|
-
});
|
|
40
|
-
/**
|
|
41
|
-
* Schema for deleting a list
|
|
42
|
-
* @property {string} id - The ID of the list to delete
|
|
43
|
-
*/
|
|
44
|
-
export const DeleteListSchema = z.object({
|
|
45
|
-
id: z.string().describe("List ID"),
|
|
46
|
-
});
|
|
47
|
-
// Response schemas
|
|
48
|
-
const ListsResponseSchema = z.object({
|
|
49
|
-
items: z.array(PlankaListSchema),
|
|
50
|
-
included: z.record(z.any()).optional(),
|
|
51
|
-
});
|
|
52
|
-
const ListResponseSchema = z.object({
|
|
53
|
-
item: PlankaListSchema,
|
|
54
|
-
included: z.record(z.any()).optional(),
|
|
55
|
-
});
|
|
56
|
-
// Function implementations
|
|
57
|
-
/**
|
|
58
|
-
* Creates a new list in a board
|
|
59
|
-
*
|
|
60
|
-
* @param {CreateListOptions} options - Options for creating the list
|
|
61
|
-
* @param {string} options.boardId - The ID of the board to create the list in
|
|
62
|
-
* @param {string} options.name - The name of the list
|
|
63
|
-
* @param {number} [options.position] - The position of the list in the board (default: 65535)
|
|
64
|
-
* @returns {Promise<object>} The created list
|
|
65
|
-
* @throws {Error} If the list creation fails
|
|
66
|
-
*/
|
|
67
|
-
export async function createList(options) {
|
|
68
|
-
try {
|
|
69
|
-
const response = await plankaRequest(`/api/boards/${options.boardId}/lists`, {
|
|
70
|
-
method: "POST",
|
|
71
|
-
body: {
|
|
72
|
-
name: options.name,
|
|
73
|
-
position: options.position,
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
const parsedResponse = ListResponseSchema.parse(response);
|
|
77
|
-
return parsedResponse.item;
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
throw new Error(`Failed to create list: ${error instanceof Error ? error.message : String(error)}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Retrieves all lists for a specific board
|
|
85
|
-
*
|
|
86
|
-
* @param {string} boardId - The ID of the board to get lists from
|
|
87
|
-
* @returns {Promise<Array<object>>} Array of lists in the board
|
|
88
|
-
*/
|
|
89
|
-
export async function getLists(boardId) {
|
|
90
|
-
try {
|
|
91
|
-
// Get the board which includes lists in the response
|
|
92
|
-
const response = await plankaRequest(`/api/boards/${boardId}`);
|
|
93
|
-
// Check if the response has the expected structure
|
|
94
|
-
if (response &&
|
|
95
|
-
typeof response === "object" &&
|
|
96
|
-
"included" in response &&
|
|
97
|
-
response.included &&
|
|
98
|
-
typeof response.included === "object" &&
|
|
99
|
-
"lists" in response.included) {
|
|
100
|
-
// Get the lists from the included property
|
|
101
|
-
const lists = response.included.lists;
|
|
102
|
-
if (Array.isArray(lists)) {
|
|
103
|
-
return lists;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// If we can't find lists in the expected format, return an empty array
|
|
107
|
-
return [];
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
// If all else fails, return an empty array
|
|
111
|
-
return [];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Retrieves a specific list by ID
|
|
116
|
-
*
|
|
117
|
-
* @param {string} id - The ID of the list to retrieve
|
|
118
|
-
* @returns {Promise<object|null>} The requested list or null if not found
|
|
119
|
-
*/
|
|
120
|
-
export async function getList(id) {
|
|
121
|
-
try {
|
|
122
|
-
const response = await plankaRequest(`/api/lists/${id}`);
|
|
123
|
-
const parsedResponse = ListResponseSchema.parse(response);
|
|
124
|
-
return parsedResponse.item;
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
console.error(`Error getting list with ID ${id}:`, error);
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Updates a list's properties
|
|
133
|
-
*
|
|
134
|
-
* @param {string} id - The ID of the list to update
|
|
135
|
-
* @param {Partial<Omit<CreateListOptions, "boardId">>} options - The properties to update
|
|
136
|
-
* @returns {Promise<object>} The updated list
|
|
137
|
-
*/
|
|
138
|
-
export async function updateList(id, options) {
|
|
139
|
-
const response = await plankaRequest(`/api/lists/${id}`, {
|
|
140
|
-
method: "PATCH",
|
|
141
|
-
body: options,
|
|
142
|
-
});
|
|
143
|
-
const parsedResponse = ListResponseSchema.parse(response);
|
|
144
|
-
return parsedResponse.item;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Deletes a list by ID
|
|
148
|
-
*
|
|
149
|
-
* @param {string} id - The ID of the list to delete
|
|
150
|
-
* @returns {Promise<{success: boolean}>} Success indicator
|
|
151
|
-
*/
|
|
152
|
-
export async function deleteList(id) {
|
|
153
|
-
await plankaRequest(`/api/lists/${id}`, {
|
|
154
|
-
method: "DELETE",
|
|
155
|
-
});
|
|
156
|
-
return { success: true };
|
|
157
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Project operations for the MCP Kanban server
|
|
3
|
-
*
|
|
4
|
-
* This module provides functions for interacting with projects in the Planka Kanban system,
|
|
5
|
-
* including creating, retrieving, updating, and deleting projects.
|
|
6
|
-
*/
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
import { plankaRequest } from "../common/utils.js";
|
|
9
|
-
import { PlankaProjectSchema } from "../common/types.js";
|
|
10
|
-
// Schema definitions
|
|
11
|
-
/**
|
|
12
|
-
* Schema for creating a new project
|
|
13
|
-
* @property {string} name - The name of the project
|
|
14
|
-
*/
|
|
15
|
-
export const CreateProjectSchema = z.object({
|
|
16
|
-
name: z.string().describe("Project name"),
|
|
17
|
-
});
|
|
18
|
-
/**
|
|
19
|
-
* Schema for retrieving projects with pagination
|
|
20
|
-
* @property {number} [page] - Page number for pagination (default: 1)
|
|
21
|
-
* @property {number} [perPage] - Number of results per page (default: 30, max: 100)
|
|
22
|
-
*/
|
|
23
|
-
export const GetProjectsSchema = z.object({
|
|
24
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
25
|
-
perPage: z.number().optional().describe("Number of results per page (default: 30, max: 100)"),
|
|
26
|
-
});
|
|
27
|
-
/**
|
|
28
|
-
* Schema for retrieving a specific project
|
|
29
|
-
* @property {string} id - The ID of the project to retrieve
|
|
30
|
-
*/
|
|
31
|
-
export const GetProjectSchema = z.object({
|
|
32
|
-
id: z.string().describe("Project ID"),
|
|
33
|
-
});
|
|
34
|
-
/**
|
|
35
|
-
* Schema for updating a project
|
|
36
|
-
* @property {string} id - The ID of the project to update
|
|
37
|
-
* @property {string} [name] - The new name for the project
|
|
38
|
-
*/
|
|
39
|
-
export const UpdateProjectSchema = z.object({
|
|
40
|
-
id: z.string().describe("Project ID"),
|
|
41
|
-
name: z.string().optional().describe("Project name"),
|
|
42
|
-
});
|
|
43
|
-
/**
|
|
44
|
-
* Schema for deleting a project
|
|
45
|
-
* @property {string} id - The ID of the project to delete
|
|
46
|
-
*/
|
|
47
|
-
export const DeleteProjectSchema = z.object({
|
|
48
|
-
id: z.string().describe("Project ID"),
|
|
49
|
-
});
|
|
50
|
-
// Response schemas
|
|
51
|
-
const ProjectsResponseSchema = z.object({
|
|
52
|
-
items: z.array(PlankaProjectSchema),
|
|
53
|
-
included: z.record(z.any()).optional(),
|
|
54
|
-
});
|
|
55
|
-
const ProjectResponseSchema = z.object({
|
|
56
|
-
item: PlankaProjectSchema,
|
|
57
|
-
included: z.record(z.any()).optional(),
|
|
58
|
-
});
|
|
59
|
-
/**
|
|
60
|
-
* Retrieves projects with pagination support
|
|
61
|
-
*
|
|
62
|
-
* @param {number} [page=1] - The page number to retrieve (1-indexed)
|
|
63
|
-
* @param {number} [perPage=30] - The number of projects per page (max: 100)
|
|
64
|
-
* @returns {Promise<{items: Array<object>, included?: object}>} Paginated projects
|
|
65
|
-
* @throws {Error} If retrieving projects fails
|
|
66
|
-
*/
|
|
67
|
-
export async function getProjects(page = 1, perPage = 30) {
|
|
68
|
-
try {
|
|
69
|
-
// Ensure perPage is within limits
|
|
70
|
-
if (perPage > 100) {
|
|
71
|
-
perPage = 100;
|
|
72
|
-
}
|
|
73
|
-
const queryParams = new URLSearchParams();
|
|
74
|
-
queryParams.append("page", page.toString());
|
|
75
|
-
queryParams.append("per_page", perPage.toString());
|
|
76
|
-
const response = await plankaRequest(`/api/projects?${queryParams.toString()}`, {
|
|
77
|
-
method: "GET",
|
|
78
|
-
});
|
|
79
|
-
const parsedResponse = ProjectsResponseSchema.parse(response);
|
|
80
|
-
return parsedResponse;
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
throw new Error(`Failed to get projects: ${error instanceof Error ? error.message : String(error)}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Retrieves a specific project by ID
|
|
88
|
-
*
|
|
89
|
-
* @param {string} id - The ID of the project to retrieve
|
|
90
|
-
* @returns {Promise<object>} The requested project
|
|
91
|
-
* @throws {Error} If retrieving the project fails
|
|
92
|
-
*/
|
|
93
|
-
export async function getProject(id) {
|
|
94
|
-
try {
|
|
95
|
-
const response = await plankaRequest(`/api/projects/${id}`);
|
|
96
|
-
const parsedResponse = ProjectResponseSchema.parse(response);
|
|
97
|
-
return parsedResponse.item;
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
throw new Error(`Failed to get project: ${error instanceof Error ? error.message : String(error)}`);
|
|
101
|
-
}
|
|
102
|
-
}
|