@omnicoreos/planka-mcp 0.2.0 → 0.3.0
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/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +26 -0
- package/.claude-plugin/plugin.json +45 -0
- package/.codex-plugin/mcp.json +16 -0
- package/.codex-plugin/plugin.json +27 -0
- package/.mcp.json +17 -0
- package/CHANGELOG.md +510 -0
- package/README.es.md +294 -55
- package/README.md +293 -55
- package/dist/cli/init.d.ts +101 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +481 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/client.d.ts +32 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +106 -32
- package/dist/client.js.map +1 -1
- package/dist/config/policy.d.ts +82 -0
- package/dist/config/policy.d.ts.map +1 -0
- package/dist/config/policy.js +226 -0
- package/dist/config/policy.js.map +1 -0
- package/dist/errors.d.ts +5 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +62 -5
- package/dist/errors.js.map +1 -1
- package/dist/identity.generated.d.ts +2 -1
- package/dist/identity.generated.d.ts.map +1 -1
- package/dist/identity.generated.js +2 -1
- package/dist/identity.generated.js.map +1 -1
- package/dist/index.js +85 -10
- package/dist/index.js.map +1 -1
- package/dist/instructions.d.ts +21 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +37 -0
- package/dist/instructions.js.map +1 -0
- package/dist/operations/actions.d.ts +654 -0
- package/dist/operations/actions.d.ts.map +1 -0
- package/dist/operations/actions.js +154 -0
- package/dist/operations/actions.js.map +1 -0
- package/dist/operations/archive.d.ts +28 -0
- package/dist/operations/archive.d.ts.map +1 -0
- package/dist/operations/archive.js +74 -0
- package/dist/operations/archive.js.map +1 -0
- package/dist/operations/attachments.d.ts +1 -1
- package/dist/operations/attachments.d.ts.map +1 -1
- package/dist/operations/attachments.js +3 -1
- package/dist/operations/attachments.js.map +1 -1
- package/dist/operations/board-id.d.ts +1 -1
- package/dist/operations/board-id.d.ts.map +1 -1
- package/dist/operations/board-id.js +13 -7
- package/dist/operations/board-id.js.map +1 -1
- package/dist/operations/boards.d.ts +96 -19
- package/dist/operations/boards.d.ts.map +1 -1
- package/dist/operations/boards.js +377 -93
- package/dist/operations/boards.js.map +1 -1
- package/dist/operations/card-brief.d.ts +91 -0
- package/dist/operations/card-brief.d.ts.map +1 -0
- package/dist/operations/card-brief.js +79 -0
- package/dist/operations/card-brief.js.map +1 -0
- package/dist/operations/cards.d.ts +34 -9
- package/dist/operations/cards.d.ts.map +1 -1
- package/dist/operations/cards.js +60 -14
- package/dist/operations/cards.js.map +1 -1
- package/dist/operations/comments.d.ts +61 -4
- package/dist/operations/comments.d.ts.map +1 -1
- package/dist/operations/comments.js +91 -8
- package/dist/operations/comments.js.map +1 -1
- package/dist/operations/duplicate.d.ts +16 -0
- package/dist/operations/duplicate.d.ts.map +1 -0
- package/dist/operations/duplicate.js +43 -0
- package/dist/operations/duplicate.js.map +1 -0
- package/dist/operations/labels.d.ts +1 -1
- package/dist/operations/labels.d.ts.map +1 -1
- package/dist/operations/labels.js +7 -4
- package/dist/operations/labels.js.map +1 -1
- package/dist/operations/lists.d.ts +63 -1
- package/dist/operations/lists.d.ts.map +1 -1
- package/dist/operations/lists.js +97 -2
- package/dist/operations/lists.js.map +1 -1
- package/dist/operations/members.d.ts +39 -0
- package/dist/operations/members.d.ts.map +1 -0
- package/dist/operations/members.js +107 -0
- package/dist/operations/members.js.map +1 -0
- package/dist/operations/projects.d.ts +16 -0
- package/dist/operations/projects.d.ts.map +1 -1
- package/dist/operations/projects.js +54 -9
- package/dist/operations/projects.js.map +1 -1
- package/dist/operations/tasks.d.ts +1 -1
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js +5 -3
- package/dist/operations/tasks.js.map +1 -1
- package/dist/operations/users.d.ts +123 -0
- package/dist/operations/users.d.ts.map +1 -0
- package/dist/operations/users.js +180 -0
- package/dist/operations/users.js.map +1 -0
- package/dist/operations/verify.d.ts +84 -0
- package/dist/operations/verify.d.ts.map +1 -0
- package/dist/operations/verify.js +124 -0
- package/dist/operations/verify.js.map +1 -0
- package/dist/prompts.d.ts +48 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +155 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +38 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +127 -0
- package/dist/resources.js.map +1 -0
- package/dist/schemas/entities.d.ts +115 -24
- package/dist/schemas/entities.d.ts.map +1 -1
- package/dist/schemas/entities.js +48 -0
- package/dist/schemas/entities.js.map +1 -1
- package/dist/schemas/requests.d.ts +121 -46
- package/dist/schemas/requests.d.ts.map +1 -1
- package/dist/schemas/requests.js +57 -12
- package/dist/schemas/requests.js.map +1 -1
- package/dist/schemas/responses.d.ts +541 -186
- package/dist/schemas/responses.d.ts.map +1 -1
- package/dist/schemas/responses.js +13 -2
- package/dist/schemas/responses.js.map +1 -1
- package/dist/tools/activity.d.ts +150 -0
- package/dist/tools/activity.d.ts.map +1 -0
- package/dist/tools/activity.js +198 -0
- package/dist/tools/activity.js.map +1 -0
- package/dist/tools/annotations.d.ts +52 -0
- package/dist/tools/annotations.d.ts.map +1 -0
- package/dist/tools/annotations.js +214 -0
- package/dist/tools/annotations.js.map +1 -0
- package/dist/tools/attachments.d.ts +28 -4
- package/dist/tools/attachments.d.ts.map +1 -1
- package/dist/tools/attachments.js +53 -34
- package/dist/tools/attachments.js.map +1 -1
- package/dist/tools/card-ops.d.ts +232 -0
- package/dist/tools/card-ops.d.ts.map +1 -0
- package/dist/tools/card-ops.js +333 -0
- package/dist/tools/card-ops.js.map +1 -0
- package/dist/tools/cards.d.ts +90 -8
- package/dist/tools/cards.d.ts.map +1 -1
- package/dist/tools/cards.js +411 -128
- package/dist/tools/cards.js.map +1 -1
- package/dist/tools/comments.d.ts +226 -22
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +163 -134
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/dispatch.d.ts +47 -0
- package/dist/tools/dispatch.d.ts.map +1 -0
- package/dist/tools/dispatch.js +63 -0
- package/dist/tools/dispatch.js.map +1 -0
- package/dist/tools/guard.d.ts +9 -0
- package/dist/tools/guard.d.ts.map +1 -0
- package/dist/tools/guard.js +20 -0
- package/dist/tools/guard.js.map +1 -0
- package/dist/tools/index.d.ts +748 -450
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +136 -17
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/labels.d.ts +213 -18
- package/dist/tools/labels.d.ts.map +1 -1
- package/dist/tools/labels.js +218 -203
- package/dist/tools/labels.js.map +1 -1
- package/dist/tools/lists.d.ts +222 -15
- package/dist/tools/lists.d.ts.map +1 -1
- package/dist/tools/lists.js +175 -156
- package/dist/tools/lists.js.map +1 -1
- package/dist/tools/members.d.ts +128 -0
- package/dist/tools/members.d.ts.map +1 -0
- package/dist/tools/members.js +150 -0
- package/dist/tools/members.js.map +1 -0
- package/dist/tools/navigation.d.ts +22 -2
- package/dist/tools/navigation.d.ts.map +1 -1
- package/dist/tools/navigation.js +60 -15
- package/dist/tools/navigation.js.map +1 -1
- package/dist/tools/queries.d.ts +196 -166
- package/dist/tools/queries.d.ts.map +1 -1
- package/dist/tools/queries.js +125 -155
- package/dist/tools/queries.js.map +1 -1
- package/dist/tools/tasks.d.ts +26 -6
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +110 -55
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/users.d.ts +130 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +165 -0
- package/dist/tools/users.js.map +1 -0
- package/docs/planka-2x-gotchas.md +121 -5
- package/docs/tools.md +771 -187
- package/docs/troubleshooting.md +137 -5
- package/hooks/hooks.json +15 -0
- package/hooks/preflight.mjs +100 -0
- package/package.json +6 -1
- package/scripts/setup.sh +8 -26
- package/scripts/sync-identity.mjs +55 -1
- package/server.json +87 -6
- package/tests/smoke/planka-smoke.mjs +512 -72
- package/workflow/skills/planka-close-card/SKILL.md +18 -5
- package/workflow/skills/planka-orchestrator/SKILL.md +36 -7
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: planka_duplicate_card
|
|
3
|
+
*/
|
|
4
|
+
export declare const duplicateCardTool: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object";
|
|
9
|
+
properties: {
|
|
10
|
+
cardId: {
|
|
11
|
+
type: string;
|
|
12
|
+
description: string;
|
|
13
|
+
};
|
|
14
|
+
listId: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
boardId: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
name: {
|
|
23
|
+
type: string;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
position: {
|
|
27
|
+
type: string;
|
|
28
|
+
description: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
required: string[];
|
|
32
|
+
};
|
|
33
|
+
handler: (params: {
|
|
34
|
+
cardId: string;
|
|
35
|
+
listId?: string;
|
|
36
|
+
boardId?: string;
|
|
37
|
+
name?: string;
|
|
38
|
+
position?: number;
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
isError?: true | undefined;
|
|
41
|
+
content: {
|
|
42
|
+
type: "text";
|
|
43
|
+
text: string;
|
|
44
|
+
}[];
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Tool: planka_archive_card
|
|
49
|
+
*/
|
|
50
|
+
export declare const archiveCardTool: {
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: "object";
|
|
55
|
+
properties: {
|
|
56
|
+
cardId: {
|
|
57
|
+
type: string;
|
|
58
|
+
description: string;
|
|
59
|
+
};
|
|
60
|
+
restoreToListId: {
|
|
61
|
+
type: string;
|
|
62
|
+
description: string;
|
|
63
|
+
};
|
|
64
|
+
position: {
|
|
65
|
+
type: string;
|
|
66
|
+
description: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
required: string[];
|
|
70
|
+
};
|
|
71
|
+
handler: (params: {
|
|
72
|
+
cardId: string;
|
|
73
|
+
restoreToListId?: string;
|
|
74
|
+
position?: number;
|
|
75
|
+
}) => Promise<{
|
|
76
|
+
isError?: true | undefined;
|
|
77
|
+
content: {
|
|
78
|
+
type: "text";
|
|
79
|
+
text: string;
|
|
80
|
+
}[];
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Tool: planka_move_list_cards
|
|
85
|
+
*
|
|
86
|
+
* Planka's own bulk endpoint looks like the implementation of this tool and is
|
|
87
|
+
* not: it only archives a whole `closed` column, and answers 403 "Not enough
|
|
88
|
+
* rights" for anything else (see `bulkMoveClosedListToArchive`). So the tool
|
|
89
|
+
* uses it where it applies and moves card by card everywhere else — the
|
|
90
|
+
* promise to the caller is the same either way, and `strategy` says which ran.
|
|
91
|
+
*/
|
|
92
|
+
export declare const moveListCardsTool: {
|
|
93
|
+
name: string;
|
|
94
|
+
description: string;
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: "object";
|
|
97
|
+
properties: {
|
|
98
|
+
fromListId: {
|
|
99
|
+
type: string;
|
|
100
|
+
description: string;
|
|
101
|
+
};
|
|
102
|
+
toListId: {
|
|
103
|
+
type: string;
|
|
104
|
+
description: string;
|
|
105
|
+
};
|
|
106
|
+
boardId: {
|
|
107
|
+
type: string;
|
|
108
|
+
description: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
required: string[];
|
|
112
|
+
};
|
|
113
|
+
handler: (params: {
|
|
114
|
+
fromListId: string;
|
|
115
|
+
toListId: string;
|
|
116
|
+
boardId?: string;
|
|
117
|
+
}) => Promise<{
|
|
118
|
+
isError?: true | undefined;
|
|
119
|
+
content: {
|
|
120
|
+
type: "text";
|
|
121
|
+
text: string;
|
|
122
|
+
}[];
|
|
123
|
+
}>;
|
|
124
|
+
};
|
|
125
|
+
export declare const cardOpsTools: ({
|
|
126
|
+
name: string;
|
|
127
|
+
description: string;
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: "object";
|
|
130
|
+
properties: {
|
|
131
|
+
cardId: {
|
|
132
|
+
type: string;
|
|
133
|
+
description: string;
|
|
134
|
+
};
|
|
135
|
+
listId: {
|
|
136
|
+
type: string;
|
|
137
|
+
description: string;
|
|
138
|
+
};
|
|
139
|
+
boardId: {
|
|
140
|
+
type: string;
|
|
141
|
+
description: string;
|
|
142
|
+
};
|
|
143
|
+
name: {
|
|
144
|
+
type: string;
|
|
145
|
+
description: string;
|
|
146
|
+
};
|
|
147
|
+
position: {
|
|
148
|
+
type: string;
|
|
149
|
+
description: string;
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
required: string[];
|
|
153
|
+
};
|
|
154
|
+
handler: (params: {
|
|
155
|
+
cardId: string;
|
|
156
|
+
listId?: string;
|
|
157
|
+
boardId?: string;
|
|
158
|
+
name?: string;
|
|
159
|
+
position?: number;
|
|
160
|
+
}) => Promise<{
|
|
161
|
+
isError?: true | undefined;
|
|
162
|
+
content: {
|
|
163
|
+
type: "text";
|
|
164
|
+
text: string;
|
|
165
|
+
}[];
|
|
166
|
+
}>;
|
|
167
|
+
} | {
|
|
168
|
+
name: string;
|
|
169
|
+
description: string;
|
|
170
|
+
inputSchema: {
|
|
171
|
+
type: "object";
|
|
172
|
+
properties: {
|
|
173
|
+
cardId: {
|
|
174
|
+
type: string;
|
|
175
|
+
description: string;
|
|
176
|
+
};
|
|
177
|
+
restoreToListId: {
|
|
178
|
+
type: string;
|
|
179
|
+
description: string;
|
|
180
|
+
};
|
|
181
|
+
position: {
|
|
182
|
+
type: string;
|
|
183
|
+
description: string;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
required: string[];
|
|
187
|
+
};
|
|
188
|
+
handler: (params: {
|
|
189
|
+
cardId: string;
|
|
190
|
+
restoreToListId?: string;
|
|
191
|
+
position?: number;
|
|
192
|
+
}) => Promise<{
|
|
193
|
+
isError?: true | undefined;
|
|
194
|
+
content: {
|
|
195
|
+
type: "text";
|
|
196
|
+
text: string;
|
|
197
|
+
}[];
|
|
198
|
+
}>;
|
|
199
|
+
} | {
|
|
200
|
+
name: string;
|
|
201
|
+
description: string;
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: "object";
|
|
204
|
+
properties: {
|
|
205
|
+
fromListId: {
|
|
206
|
+
type: string;
|
|
207
|
+
description: string;
|
|
208
|
+
};
|
|
209
|
+
toListId: {
|
|
210
|
+
type: string;
|
|
211
|
+
description: string;
|
|
212
|
+
};
|
|
213
|
+
boardId: {
|
|
214
|
+
type: string;
|
|
215
|
+
description: string;
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
required: string[];
|
|
219
|
+
};
|
|
220
|
+
handler: (params: {
|
|
221
|
+
fromListId: string;
|
|
222
|
+
toListId: string;
|
|
223
|
+
boardId?: string;
|
|
224
|
+
}) => Promise<{
|
|
225
|
+
isError?: true | undefined;
|
|
226
|
+
content: {
|
|
227
|
+
type: "text";
|
|
228
|
+
text: string;
|
|
229
|
+
}[];
|
|
230
|
+
}>;
|
|
231
|
+
})[];
|
|
232
|
+
//# sourceMappingURL=card-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-ops.d.ts","sourceRoot":"","sources":["../../src/tools/card-ops.ts"],"names":[],"mappings":"AAmCA;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA0BJ;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;;CA0CF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;sBAqBF;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;;CA4GF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;sBAiBJ;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;;;;;;;CA8GF,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA1UC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAoEuB;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAwIuB;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;;;;;;;IAgHgF,CAAC"}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Card operations Planka has that this server did not expose: duplicating a
|
|
3
|
+
* card, archiving one, and emptying a column into another.
|
|
4
|
+
*
|
|
5
|
+
* All three are verified the same way the rest of the server is: the write is
|
|
6
|
+
* sent, the entity is read back, and the report describes the re-read.
|
|
7
|
+
*/
|
|
8
|
+
import { duplicateCard } from "../operations/duplicate.js";
|
|
9
|
+
import { getCardBrief } from "../operations/card-brief.js";
|
|
10
|
+
import { getBoardSystemLists, moveCardToList, noArchiveList, } from "../operations/archive.js";
|
|
11
|
+
import { bulkMoveClosedListToArchive, moveCardsOneByOne, readListState, } from "../operations/lists.js";
|
|
12
|
+
import { verifiedWrite, writeResult } from "../operations/verify.js";
|
|
13
|
+
import { assertBoardAllowed, assertListWritable } from "../config/policy.js";
|
|
14
|
+
import { PlankaError } from "../errors.js";
|
|
15
|
+
function errorResult(message) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
18
|
+
isError: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function catchPlanka(error) {
|
|
22
|
+
if (error instanceof PlankaError)
|
|
23
|
+
return errorResult(error.message);
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Tool: planka_duplicate_card
|
|
28
|
+
*/
|
|
29
|
+
export const duplicateCardTool = {
|
|
30
|
+
name: "planka_duplicate_card",
|
|
31
|
+
description: "Copy a card with its tasks, labels and members (attachments are not copied). Lands in the " +
|
|
32
|
+
"same column unless listId says otherwise. Re-reads the copy and reports what it carries.",
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: "object",
|
|
35
|
+
properties: {
|
|
36
|
+
cardId: { type: "string", description: "The card to copy" },
|
|
37
|
+
listId: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Column for the copy. Defaults to the original's column.",
|
|
40
|
+
},
|
|
41
|
+
boardId: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Board for the copy, when copying across boards. Requires listId.",
|
|
44
|
+
},
|
|
45
|
+
name: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Name for the copy. Without it Planka appends its own suffix to the original name.",
|
|
48
|
+
},
|
|
49
|
+
position: { type: "number", description: "Position in the target column" },
|
|
50
|
+
},
|
|
51
|
+
required: ["cardId"],
|
|
52
|
+
},
|
|
53
|
+
handler: async (params) => {
|
|
54
|
+
try {
|
|
55
|
+
if (params.boardId && !params.listId) {
|
|
56
|
+
return errorResult("boardId without listId: a copy sent to another board needs the column it lands in.");
|
|
57
|
+
}
|
|
58
|
+
const written = await verifiedWrite({
|
|
59
|
+
write: () => duplicateCard(params),
|
|
60
|
+
reread: (copy) => getCardBrief({ cardId: copy.id }),
|
|
61
|
+
landed: (after, copy) => {
|
|
62
|
+
if (after.card.id !== copy.id)
|
|
63
|
+
return false;
|
|
64
|
+
if (params.listId && after.card.listId !== params.listId)
|
|
65
|
+
return false;
|
|
66
|
+
if (params.name !== undefined && after.card.name !== params.name)
|
|
67
|
+
return false;
|
|
68
|
+
return true;
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
const after = written.after;
|
|
72
|
+
return writeResult({
|
|
73
|
+
card: {
|
|
74
|
+
id: written.result.id,
|
|
75
|
+
name: after?.card.name ?? written.result.name,
|
|
76
|
+
listId: after?.card.listId ?? written.result.listId,
|
|
77
|
+
boardId: after?.card.boardId ?? written.result.boardId,
|
|
78
|
+
},
|
|
79
|
+
sourceCardId: params.cardId,
|
|
80
|
+
copied: {
|
|
81
|
+
tasks: after?.counts.tasks ?? 0,
|
|
82
|
+
labels: after?.counts.labels ?? 0,
|
|
83
|
+
members: after?.counts.members ?? 0,
|
|
84
|
+
attachments: after?.counts.attachments ?? 0,
|
|
85
|
+
},
|
|
86
|
+
}, written);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return catchPlanka(error);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Tool: planka_archive_card
|
|
95
|
+
*/
|
|
96
|
+
export const archiveCardTool = {
|
|
97
|
+
name: "planka_archive_card",
|
|
98
|
+
description: "Archive a card (Planka's hidden archive column) or bring it back with restoreToListId. " +
|
|
99
|
+
"Archiving hides the card from the board without deleting it; verified by re-reading its column.",
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: "object",
|
|
102
|
+
properties: {
|
|
103
|
+
cardId: { type: "string", description: "The card ID" },
|
|
104
|
+
restoreToListId: {
|
|
105
|
+
type: "string",
|
|
106
|
+
description: "Un-archive instead: move the card into this column. The card's previous column is reported when archiving.",
|
|
107
|
+
},
|
|
108
|
+
position: {
|
|
109
|
+
type: "number",
|
|
110
|
+
description: "Position in the column when restoring. Defaults to the end.",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
required: ["cardId"],
|
|
114
|
+
},
|
|
115
|
+
handler: async (params) => {
|
|
116
|
+
try {
|
|
117
|
+
const before = await getCardBrief({ cardId: params.cardId });
|
|
118
|
+
const boardId = before.card.boardId;
|
|
119
|
+
// --- restore ---------------------------------------------------------
|
|
120
|
+
if (params.restoreToListId) {
|
|
121
|
+
assertListWritable(params.restoreToListId, undefined, "restore cards into");
|
|
122
|
+
const written = await verifiedWrite({
|
|
123
|
+
write: () => moveCardToList({
|
|
124
|
+
cardId: params.cardId,
|
|
125
|
+
listId: params.restoreToListId,
|
|
126
|
+
// An archived card has position null and Planka refuses a PATCH
|
|
127
|
+
// without one, so a restore always carries a position.
|
|
128
|
+
position: params.position ?? 65536,
|
|
129
|
+
}),
|
|
130
|
+
reread: () => getCardBrief({ cardId: params.cardId }),
|
|
131
|
+
landed: (after) => after.card.listId === params.restoreToListId,
|
|
132
|
+
});
|
|
133
|
+
return writeResult({
|
|
134
|
+
card: {
|
|
135
|
+
id: params.cardId,
|
|
136
|
+
name: written.after?.card.name ?? before.card.name,
|
|
137
|
+
listId: written.after?.card.listId ?? before.card.listId,
|
|
138
|
+
},
|
|
139
|
+
archived: false,
|
|
140
|
+
restoredTo: params.restoreToListId,
|
|
141
|
+
previousListId: before.card.listId,
|
|
142
|
+
}, written);
|
|
143
|
+
}
|
|
144
|
+
// --- archive ---------------------------------------------------------
|
|
145
|
+
// Archiving takes the card OUT of its column, so the origin is checked
|
|
146
|
+
// too — otherwise a protected column can be emptied one archive at a time.
|
|
147
|
+
assertListWritable(before.card.listId, undefined, "archive cards out of");
|
|
148
|
+
const system = await getBoardSystemLists(boardId);
|
|
149
|
+
if (!system.archiveListId)
|
|
150
|
+
throw noArchiveList(boardId);
|
|
151
|
+
assertListWritable(system.archiveListId, undefined, "archive cards into");
|
|
152
|
+
if (before.card.listId === system.archiveListId) {
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
text: JSON.stringify({
|
|
158
|
+
success: true,
|
|
159
|
+
// Derived from the read above, not asserted: `before` IS the
|
|
160
|
+
// re-read, and it already says the card sits in the archive.
|
|
161
|
+
verified: true,
|
|
162
|
+
verifiedBy: "the card was read before the write and is already archived; nothing was written",
|
|
163
|
+
card: {
|
|
164
|
+
id: before.card.id,
|
|
165
|
+
name: before.card.name,
|
|
166
|
+
listId: before.card.listId,
|
|
167
|
+
},
|
|
168
|
+
archived: true,
|
|
169
|
+
alreadyArchived: true,
|
|
170
|
+
archiveListId: system.archiveListId,
|
|
171
|
+
previousListId: before.card.prevListId ?? null,
|
|
172
|
+
message: "The card was already in the archive. Pass restoreToListId to bring it back" +
|
|
173
|
+
(before.card.prevListId
|
|
174
|
+
? ` (it came from list ${before.card.prevListId}).`
|
|
175
|
+
: "."),
|
|
176
|
+
}),
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const written = await verifiedWrite({
|
|
182
|
+
write: () => moveCardToList({ cardId: params.cardId, listId: system.archiveListId }),
|
|
183
|
+
reread: () => getCardBrief({ cardId: params.cardId }),
|
|
184
|
+
// isClosed does NOT flip on archive (verified on 2.2.1), so the column
|
|
185
|
+
// is the only honest proof.
|
|
186
|
+
landed: (after) => after.card.listId === system.archiveListId &&
|
|
187
|
+
after.card.listId !== before.card.listId,
|
|
188
|
+
});
|
|
189
|
+
return writeResult({
|
|
190
|
+
card: {
|
|
191
|
+
id: before.card.id,
|
|
192
|
+
name: written.after?.card.name ?? before.card.name,
|
|
193
|
+
listId: written.after?.card.listId ?? system.archiveListId,
|
|
194
|
+
},
|
|
195
|
+
archived: written.verified,
|
|
196
|
+
archiveListId: system.archiveListId,
|
|
197
|
+
previousListId: before.card.listId,
|
|
198
|
+
message: written.verified
|
|
199
|
+
? `Card archived. Restore it with restoreToListId: "${before.card.listId}".`
|
|
200
|
+
: "The card does not read as archived.",
|
|
201
|
+
}, written);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return catchPlanka(error);
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Tool: planka_move_list_cards
|
|
210
|
+
*
|
|
211
|
+
* Planka's own bulk endpoint looks like the implementation of this tool and is
|
|
212
|
+
* not: it only archives a whole `closed` column, and answers 403 "Not enough
|
|
213
|
+
* rights" for anything else (see `bulkMoveClosedListToArchive`). So the tool
|
|
214
|
+
* uses it where it applies and moves card by card everywhere else — the
|
|
215
|
+
* promise to the caller is the same either way, and `strategy` says which ran.
|
|
216
|
+
*/
|
|
217
|
+
export const moveListCardsTool = {
|
|
218
|
+
name: "planka_move_list_cards",
|
|
219
|
+
description: "Move EVERY card of one column into another. Counts both columns before and after; verified " +
|
|
220
|
+
"is false when the numbers do not add up. Reports partial moves rather than a smaller success.",
|
|
221
|
+
inputSchema: {
|
|
222
|
+
type: "object",
|
|
223
|
+
properties: {
|
|
224
|
+
fromListId: { type: "string", description: "Column to empty" },
|
|
225
|
+
toListId: { type: "string", description: "Column that receives the cards" },
|
|
226
|
+
boardId: {
|
|
227
|
+
type: "string",
|
|
228
|
+
description: "Board both columns belong to. Checked against the allowlist when given.",
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ["fromListId", "toListId"],
|
|
232
|
+
},
|
|
233
|
+
handler: async (params) => {
|
|
234
|
+
try {
|
|
235
|
+
if (params.fromListId === params.toListId) {
|
|
236
|
+
return errorResult("fromListId and toListId are the same column: nothing would move.");
|
|
237
|
+
}
|
|
238
|
+
if (params.boardId)
|
|
239
|
+
assertBoardAllowed(params.boardId);
|
|
240
|
+
assertListWritable(params.toListId, undefined, "move cards into");
|
|
241
|
+
assertListWritable(params.fromListId, undefined, "move cards out of");
|
|
242
|
+
const from = await readListState(params.fromListId);
|
|
243
|
+
if (!from) {
|
|
244
|
+
return errorResult(`List ${params.fromListId} cannot be read. Planka's hidden archive and trash lists ` +
|
|
245
|
+
`answer 404 here, and so does a list id that does not exist.`);
|
|
246
|
+
}
|
|
247
|
+
// The destination may legitimately be unreadable: the archive list is.
|
|
248
|
+
const to = await readListState(params.toListId);
|
|
249
|
+
const toBefore = to?.count ?? null;
|
|
250
|
+
if (from.count === 0) {
|
|
251
|
+
return {
|
|
252
|
+
content: [
|
|
253
|
+
{
|
|
254
|
+
type: "text",
|
|
255
|
+
text: JSON.stringify({
|
|
256
|
+
success: true,
|
|
257
|
+
// `from.count === 0` comes from readListState, a real read of
|
|
258
|
+
// the column: the desired state already holds, nothing written.
|
|
259
|
+
verified: true,
|
|
260
|
+
verifiedBy: "the source column was read and is already empty; nothing was written",
|
|
261
|
+
moved: 0,
|
|
262
|
+
fromRemaining: 0,
|
|
263
|
+
toTotal: toBefore,
|
|
264
|
+
message: `List ${params.fromListId} is already empty; nothing was moved.`,
|
|
265
|
+
}),
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// Planka's bulk call only accepts closed -> archive. Everywhere else it
|
|
271
|
+
// answers 403, so it is not even attempted. The board show that resolves
|
|
272
|
+
// the archive id is expensive, so it is only read when the destination
|
|
273
|
+
// could BE the archive — an unreadable list — and the source is closed.
|
|
274
|
+
let canBulk = false;
|
|
275
|
+
if (from.type === "closed" && to === null && from.boardId) {
|
|
276
|
+
const { archiveListId } = await getBoardSystemLists(from.boardId);
|
|
277
|
+
canBulk = archiveListId === params.toListId;
|
|
278
|
+
}
|
|
279
|
+
const cards = from.cardIds.map((id) => ({
|
|
280
|
+
id,
|
|
281
|
+
position: from.positions.get(id) ?? null,
|
|
282
|
+
}));
|
|
283
|
+
let failed = [];
|
|
284
|
+
const written = await verifiedWrite({
|
|
285
|
+
write: async () => {
|
|
286
|
+
if (canBulk) {
|
|
287
|
+
await bulkMoveClosedListToArchive({
|
|
288
|
+
fromListId: params.fromListId,
|
|
289
|
+
toListId: params.toListId,
|
|
290
|
+
});
|
|
291
|
+
return "bulk";
|
|
292
|
+
}
|
|
293
|
+
failed = await moveCardsOneByOne({ cards, toListId: params.toListId });
|
|
294
|
+
return "perCard";
|
|
295
|
+
},
|
|
296
|
+
reread: async () => ({
|
|
297
|
+
from: (await readListState(params.fromListId))?.count ?? null,
|
|
298
|
+
to: (await readListState(params.toListId))?.count ?? null,
|
|
299
|
+
}),
|
|
300
|
+
landed: (after) => {
|
|
301
|
+
if (after.from !== 0)
|
|
302
|
+
return false;
|
|
303
|
+
// An unreadable destination (the archive) cannot be counted; an empty
|
|
304
|
+
// source plus no failed PATCH is the whole proof available.
|
|
305
|
+
if (after.to === null || toBefore === null)
|
|
306
|
+
return failed.length === 0;
|
|
307
|
+
return after.to === toBefore + from.count;
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
const fromAfter = written.after?.from ?? from.count;
|
|
311
|
+
const toAfter = written.after?.to ?? toBefore;
|
|
312
|
+
return writeResult({
|
|
313
|
+
fromListId: params.fromListId,
|
|
314
|
+
toListId: params.toListId,
|
|
315
|
+
strategy: written.result,
|
|
316
|
+
moved: from.count - (fromAfter ?? from.count),
|
|
317
|
+
fromRemaining: fromAfter,
|
|
318
|
+
toTotal: toAfter,
|
|
319
|
+
...(toBefore === null
|
|
320
|
+
? {
|
|
321
|
+
toCountUnavailable: "the destination list cannot be read (Planka hides archive and trash), so only the source was counted",
|
|
322
|
+
}
|
|
323
|
+
: { expectedTotal: toBefore + from.count }),
|
|
324
|
+
...(failed.length ? { failed } : {}),
|
|
325
|
+
}, written);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
return catchPlanka(error);
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
export const cardOpsTools = [duplicateCardTool, archiveCardTool, moveListCardsTool];
|
|
333
|
+
//# sourceMappingURL=card-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-ops.js","sourceRoot":"","sources":["../../src/tools/card-ops.ts"],"names":[],"mappings":"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"}
|