@chorus-aidlc/openclaw-plugin 0.1.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/README.md +287 -0
- package/images/slug.png +0 -0
- package/openclaw.plugin.json +29 -0
- package/package.json +37 -0
- package/src/commands.ts +141 -0
- package/src/config.ts +24 -0
- package/src/event-router.ts +228 -0
- package/src/index.ts +132 -0
- package/src/mcp-client.ts +141 -0
- package/src/sse-listener.ts +184 -0
- package/src/tools/common-tools.ts +418 -0
- package/src/tools/dev-tools.ts +85 -0
- package/src/tools/pm-tools.ts +356 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import type { ChorusMcpClient } from "../mcp-client.js";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export function registerCommonTools(api: any, mcpClient: ChorusMcpClient) {
|
|
5
|
+
api.registerTool({
|
|
6
|
+
name: "chorus_checkin",
|
|
7
|
+
description: "Agent check-in. Returns persona, roles, and pending assignments. Recommended at session start.",
|
|
8
|
+
parameters: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {},
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
},
|
|
13
|
+
async execute() {
|
|
14
|
+
const result = await mcpClient.callTool("chorus_checkin", {});
|
|
15
|
+
return JSON.stringify(result, null, 2);
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
api.registerTool({
|
|
20
|
+
name: "chorus_get_notifications",
|
|
21
|
+
description: "Get notifications. By default fetches unread and auto-marks them as read.",
|
|
22
|
+
parameters: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
status: { type: "string", description: "Filter: unread | read | all (default: unread)" },
|
|
26
|
+
autoMarkRead: { type: "boolean", description: "Auto-mark fetched unread as read (default: true)" },
|
|
27
|
+
},
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
},
|
|
30
|
+
async execute(_id: string, { status, autoMarkRead }: { status?: string; autoMarkRead?: boolean }) {
|
|
31
|
+
const args: Record<string, unknown> = {};
|
|
32
|
+
if (status) args.status = status;
|
|
33
|
+
if (autoMarkRead !== undefined) args.autoMarkRead = autoMarkRead;
|
|
34
|
+
const result = await mcpClient.callTool("chorus_get_notifications", args);
|
|
35
|
+
return JSON.stringify(result, null, 2);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
api.registerTool({
|
|
40
|
+
name: "chorus_get_project",
|
|
41
|
+
description: "Get project details and context",
|
|
42
|
+
parameters: {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
46
|
+
},
|
|
47
|
+
required: ["projectUuid"],
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
},
|
|
50
|
+
async execute(_id: string, { projectUuid }: { projectUuid: string }) {
|
|
51
|
+
const result = await mcpClient.callTool("chorus_get_project", { projectUuid });
|
|
52
|
+
return JSON.stringify(result, null, 2);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
api.registerTool({
|
|
57
|
+
name: "chorus_get_task",
|
|
58
|
+
description: "Get detailed information and context for a single task",
|
|
59
|
+
parameters: {
|
|
60
|
+
type: "object",
|
|
61
|
+
properties: {
|
|
62
|
+
taskUuid: { type: "string", description: "Task UUID" },
|
|
63
|
+
},
|
|
64
|
+
required: ["taskUuid"],
|
|
65
|
+
additionalProperties: false,
|
|
66
|
+
},
|
|
67
|
+
async execute(_id: string, { taskUuid }: { taskUuid: string }) {
|
|
68
|
+
const result = await mcpClient.callTool("chorus_get_task", { taskUuid });
|
|
69
|
+
return JSON.stringify(result, null, 2);
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
api.registerTool({
|
|
74
|
+
name: "chorus_get_idea",
|
|
75
|
+
description: "Get detailed information for a single idea",
|
|
76
|
+
parameters: {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
ideaUuid: { type: "string", description: "Idea UUID" },
|
|
80
|
+
},
|
|
81
|
+
required: ["ideaUuid"],
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
},
|
|
84
|
+
async execute(_id: string, { ideaUuid }: { ideaUuid: string }) {
|
|
85
|
+
const result = await mcpClient.callTool("chorus_get_idea", { ideaUuid });
|
|
86
|
+
return JSON.stringify(result, null, 2);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
api.registerTool({
|
|
91
|
+
name: "chorus_get_available_tasks",
|
|
92
|
+
description: "Get tasks available to claim in a project (status=open)",
|
|
93
|
+
parameters: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {
|
|
96
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
97
|
+
},
|
|
98
|
+
required: ["projectUuid"],
|
|
99
|
+
additionalProperties: false,
|
|
100
|
+
},
|
|
101
|
+
async execute(_id: string, { projectUuid }: { projectUuid: string }) {
|
|
102
|
+
const result = await mcpClient.callTool("chorus_get_available_tasks", { projectUuid });
|
|
103
|
+
return JSON.stringify(result, null, 2);
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
api.registerTool({
|
|
108
|
+
name: "chorus_get_available_ideas",
|
|
109
|
+
description: "Get ideas available to claim in a project (status=open)",
|
|
110
|
+
parameters: {
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: {
|
|
113
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
114
|
+
},
|
|
115
|
+
required: ["projectUuid"],
|
|
116
|
+
additionalProperties: false,
|
|
117
|
+
},
|
|
118
|
+
async execute(_id: string, { projectUuid }: { projectUuid: string }) {
|
|
119
|
+
const result = await mcpClient.callTool("chorus_get_available_ideas", { projectUuid });
|
|
120
|
+
return JSON.stringify(result, null, 2);
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// --- List tools for project exploration ---
|
|
125
|
+
|
|
126
|
+
api.registerTool({
|
|
127
|
+
name: "chorus_list_projects",
|
|
128
|
+
description: "List all projects for the current company. Returns projects with counts of ideas, documents, tasks, and proposals.",
|
|
129
|
+
parameters: {
|
|
130
|
+
type: "object",
|
|
131
|
+
properties: {
|
|
132
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
133
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
134
|
+
},
|
|
135
|
+
additionalProperties: false,
|
|
136
|
+
},
|
|
137
|
+
async execute(_id: string, { page, pageSize }: { page?: number; pageSize?: number }) {
|
|
138
|
+
const args: Record<string, unknown> = {};
|
|
139
|
+
if (page !== undefined) args.page = page;
|
|
140
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
141
|
+
const result = await mcpClient.callTool("chorus_list_projects", args);
|
|
142
|
+
return JSON.stringify(result, null, 2);
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
api.registerTool({
|
|
147
|
+
name: "chorus_list_tasks",
|
|
148
|
+
description: "List tasks for a project. Can filter by status and priority.",
|
|
149
|
+
parameters: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
153
|
+
status: { type: "string", description: "Filter by status: open | assigned | in_progress | to_verify | done | closed" },
|
|
154
|
+
priority: { type: "string", description: "Filter by priority: low | medium | high" },
|
|
155
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
156
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
157
|
+
},
|
|
158
|
+
required: ["projectUuid"],
|
|
159
|
+
additionalProperties: false,
|
|
160
|
+
},
|
|
161
|
+
async execute(_id: string, { projectUuid, status, priority, page, pageSize }: { projectUuid: string; status?: string; priority?: string; page?: number; pageSize?: number }) {
|
|
162
|
+
const args: Record<string, unknown> = { projectUuid };
|
|
163
|
+
if (status) args.status = status;
|
|
164
|
+
if (priority) args.priority = priority;
|
|
165
|
+
if (page !== undefined) args.page = page;
|
|
166
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
167
|
+
const result = await mcpClient.callTool("chorus_list_tasks", args);
|
|
168
|
+
return JSON.stringify(result, null, 2);
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
api.registerTool({
|
|
173
|
+
name: "chorus_get_ideas",
|
|
174
|
+
description: "List ideas for a project. Can filter by status.",
|
|
175
|
+
parameters: {
|
|
176
|
+
type: "object",
|
|
177
|
+
properties: {
|
|
178
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
179
|
+
status: { type: "string", description: "Filter by status: open | elaborating | proposal_created | completed | closed" },
|
|
180
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
181
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
182
|
+
},
|
|
183
|
+
required: ["projectUuid"],
|
|
184
|
+
additionalProperties: false,
|
|
185
|
+
},
|
|
186
|
+
async execute(_id: string, { projectUuid, status, page, pageSize }: { projectUuid: string; status?: string; page?: number; pageSize?: number }) {
|
|
187
|
+
const args: Record<string, unknown> = { projectUuid };
|
|
188
|
+
if (status) args.status = status;
|
|
189
|
+
if (page !== undefined) args.page = page;
|
|
190
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
191
|
+
const result = await mcpClient.callTool("chorus_get_ideas", args);
|
|
192
|
+
return JSON.stringify(result, null, 2);
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
api.registerTool({
|
|
197
|
+
name: "chorus_get_proposals",
|
|
198
|
+
description: "List proposals for a project. Can filter by status.",
|
|
199
|
+
parameters: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
203
|
+
status: { type: "string", description: "Filter by status: draft | pending | approved | rejected" },
|
|
204
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
205
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
206
|
+
},
|
|
207
|
+
required: ["projectUuid"],
|
|
208
|
+
additionalProperties: false,
|
|
209
|
+
},
|
|
210
|
+
async execute(_id: string, { projectUuid, status, page, pageSize }: { projectUuid: string; status?: string; page?: number; pageSize?: number }) {
|
|
211
|
+
const args: Record<string, unknown> = { projectUuid };
|
|
212
|
+
if (status) args.status = status;
|
|
213
|
+
if (page !== undefined) args.page = page;
|
|
214
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
215
|
+
const result = await mcpClient.callTool("chorus_get_proposals", args);
|
|
216
|
+
return JSON.stringify(result, null, 2);
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
api.registerTool({
|
|
221
|
+
name: "chorus_get_documents",
|
|
222
|
+
description: "List documents for a project. Can filter by type.",
|
|
223
|
+
parameters: {
|
|
224
|
+
type: "object",
|
|
225
|
+
properties: {
|
|
226
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
227
|
+
type: { type: "string", description: "Filter by type: prd | tech_design | adr | spec | guide" },
|
|
228
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
229
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
230
|
+
},
|
|
231
|
+
required: ["projectUuid"],
|
|
232
|
+
additionalProperties: false,
|
|
233
|
+
},
|
|
234
|
+
async execute(_id: string, { projectUuid, type, page, pageSize }: { projectUuid: string; type?: string; page?: number; pageSize?: number }) {
|
|
235
|
+
const args: Record<string, unknown> = { projectUuid };
|
|
236
|
+
if (type) args.type = type;
|
|
237
|
+
if (page !== undefined) args.page = page;
|
|
238
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
239
|
+
const result = await mcpClient.callTool("chorus_get_documents", args);
|
|
240
|
+
return JSON.stringify(result, null, 2);
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
api.registerTool({
|
|
245
|
+
name: "chorus_get_document",
|
|
246
|
+
description: "Get the detailed content of a single document.",
|
|
247
|
+
parameters: {
|
|
248
|
+
type: "object",
|
|
249
|
+
properties: {
|
|
250
|
+
documentUuid: { type: "string", description: "Document UUID" },
|
|
251
|
+
},
|
|
252
|
+
required: ["documentUuid"],
|
|
253
|
+
additionalProperties: false,
|
|
254
|
+
},
|
|
255
|
+
async execute(_id: string, { documentUuid }: { documentUuid: string }) {
|
|
256
|
+
const result = await mcpClient.callTool("chorus_get_document", { documentUuid });
|
|
257
|
+
return JSON.stringify(result, null, 2);
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
api.registerTool({
|
|
262
|
+
name: "chorus_get_unblocked_tasks",
|
|
263
|
+
description: "Get tasks that are ready to start — status is open/assigned and all dependencies are resolved (done/to_verify).",
|
|
264
|
+
parameters: {
|
|
265
|
+
type: "object",
|
|
266
|
+
properties: {
|
|
267
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
268
|
+
},
|
|
269
|
+
required: ["projectUuid"],
|
|
270
|
+
additionalProperties: false,
|
|
271
|
+
},
|
|
272
|
+
async execute(_id: string, { projectUuid }: { projectUuid: string }) {
|
|
273
|
+
const result = await mcpClient.callTool("chorus_get_unblocked_tasks", { projectUuid });
|
|
274
|
+
return JSON.stringify(result, null, 2);
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
api.registerTool({
|
|
279
|
+
name: "chorus_get_activity",
|
|
280
|
+
description: "Get the activity stream for a project. Shows all actions taken by agents and users.",
|
|
281
|
+
parameters: {
|
|
282
|
+
type: "object",
|
|
283
|
+
properties: {
|
|
284
|
+
projectUuid: { type: "string", description: "Project UUID" },
|
|
285
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
286
|
+
pageSize: { type: "number", description: "Items per page (default: 50)" },
|
|
287
|
+
},
|
|
288
|
+
required: ["projectUuid"],
|
|
289
|
+
additionalProperties: false,
|
|
290
|
+
},
|
|
291
|
+
async execute(_id: string, { projectUuid, page, pageSize }: { projectUuid: string; page?: number; pageSize?: number }) {
|
|
292
|
+
const args: Record<string, unknown> = { projectUuid };
|
|
293
|
+
if (page !== undefined) args.page = page;
|
|
294
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
295
|
+
const result = await mcpClient.callTool("chorus_get_activity", args);
|
|
296
|
+
return JSON.stringify(result, null, 2);
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
api.registerTool({
|
|
301
|
+
name: "chorus_get_comments",
|
|
302
|
+
description: "Get comments for an Idea, Proposal, Task, or Document. Useful for understanding context, decisions, and feedback.",
|
|
303
|
+
parameters: {
|
|
304
|
+
type: "object",
|
|
305
|
+
properties: {
|
|
306
|
+
targetType: { type: "string", description: "Target type: idea | proposal | task | document" },
|
|
307
|
+
targetUuid: { type: "string", description: "Target UUID" },
|
|
308
|
+
page: { type: "number", description: "Page number (default: 1)" },
|
|
309
|
+
pageSize: { type: "number", description: "Items per page (default: 20)" },
|
|
310
|
+
},
|
|
311
|
+
required: ["targetType", "targetUuid"],
|
|
312
|
+
additionalProperties: false,
|
|
313
|
+
},
|
|
314
|
+
async execute(_id: string, { targetType, targetUuid, page, pageSize }: { targetType: string; targetUuid: string; page?: number; pageSize?: number }) {
|
|
315
|
+
const args: Record<string, unknown> = { targetType, targetUuid };
|
|
316
|
+
if (page !== undefined) args.page = page;
|
|
317
|
+
if (pageSize !== undefined) args.pageSize = pageSize;
|
|
318
|
+
const result = await mcpClient.callTool("chorus_get_comments", args);
|
|
319
|
+
return JSON.stringify(result, null, 2);
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
api.registerTool({
|
|
324
|
+
name: "chorus_get_elaboration",
|
|
325
|
+
description: "Get the full elaboration state for an Idea, including all rounds, questions, answers, and progress summary.",
|
|
326
|
+
parameters: {
|
|
327
|
+
type: "object",
|
|
328
|
+
properties: {
|
|
329
|
+
ideaUuid: { type: "string", description: "Idea UUID" },
|
|
330
|
+
},
|
|
331
|
+
required: ["ideaUuid"],
|
|
332
|
+
additionalProperties: false,
|
|
333
|
+
},
|
|
334
|
+
async execute(_id: string, { ideaUuid }: { ideaUuid: string }) {
|
|
335
|
+
const result = await mcpClient.callTool("chorus_get_elaboration", { ideaUuid });
|
|
336
|
+
return JSON.stringify(result, null, 2);
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
api.registerTool({
|
|
341
|
+
name: "chorus_get_my_assignments",
|
|
342
|
+
description: "Get all Ideas and Tasks currently assigned to you.",
|
|
343
|
+
parameters: {
|
|
344
|
+
type: "object",
|
|
345
|
+
properties: {},
|
|
346
|
+
additionalProperties: false,
|
|
347
|
+
},
|
|
348
|
+
async execute() {
|
|
349
|
+
const result = await mcpClient.callTool("chorus_get_my_assignments", {});
|
|
350
|
+
return JSON.stringify(result, null, 2);
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// --- Admin tools ---
|
|
355
|
+
|
|
356
|
+
api.registerTool({
|
|
357
|
+
name: "chorus_admin_create_project",
|
|
358
|
+
description: "Create a new project. Call chorus_get_project_groups first to find the right groupUuid.",
|
|
359
|
+
parameters: {
|
|
360
|
+
type: "object",
|
|
361
|
+
properties: {
|
|
362
|
+
name: { type: "string", description: "Project name" },
|
|
363
|
+
description: { type: "string", description: "Project description" },
|
|
364
|
+
groupUuid: { type: "string", description: "Project group UUID (optional, use chorus_get_project_groups to list groups)" },
|
|
365
|
+
},
|
|
366
|
+
required: ["name"],
|
|
367
|
+
additionalProperties: false,
|
|
368
|
+
},
|
|
369
|
+
async execute(_id: string, { name, description, groupUuid }: { name: string; description?: string; groupUuid?: string }) {
|
|
370
|
+
const args: Record<string, unknown> = { name };
|
|
371
|
+
if (description) args.description = description;
|
|
372
|
+
if (groupUuid) args.groupUuid = groupUuid;
|
|
373
|
+
const result = await mcpClient.callTool("chorus_admin_create_project", args);
|
|
374
|
+
return JSON.stringify(result, null, 2);
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// --- Write tools ---
|
|
379
|
+
|
|
380
|
+
api.registerTool({
|
|
381
|
+
name: "chorus_add_comment",
|
|
382
|
+
description: "Add a comment to an Idea, Proposal, Task, or Document",
|
|
383
|
+
parameters: {
|
|
384
|
+
type: "object",
|
|
385
|
+
properties: {
|
|
386
|
+
targetType: { type: "string", description: "Target type: idea | proposal | task | document" },
|
|
387
|
+
targetUuid: { type: "string", description: "Target UUID" },
|
|
388
|
+
content: { type: "string", description: "Comment content" },
|
|
389
|
+
},
|
|
390
|
+
required: ["targetType", "targetUuid", "content"],
|
|
391
|
+
additionalProperties: false,
|
|
392
|
+
},
|
|
393
|
+
async execute(_id: string, { targetType, targetUuid, content }: { targetType: string; targetUuid: string; content: string }) {
|
|
394
|
+
const result = await mcpClient.callTool("chorus_add_comment", { targetType, targetUuid, content });
|
|
395
|
+
return JSON.stringify(result, null, 2);
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
api.registerTool({
|
|
400
|
+
name: "chorus_search_mentionables",
|
|
401
|
+
description: "Search for users and agents that can be @mentioned. Returns name, type, and UUID. Use the UUID to write mentions as @[Name](type:uuid) in comment text.",
|
|
402
|
+
parameters: {
|
|
403
|
+
type: "object",
|
|
404
|
+
properties: {
|
|
405
|
+
query: { type: "string", description: "Name or keyword to search" },
|
|
406
|
+
limit: { type: "number", description: "Max results to return (default 10)" },
|
|
407
|
+
},
|
|
408
|
+
required: ["query"],
|
|
409
|
+
additionalProperties: false,
|
|
410
|
+
},
|
|
411
|
+
async execute(_id: string, { query, limit }: { query: string; limit?: number }) {
|
|
412
|
+
const args: Record<string, unknown> = { query };
|
|
413
|
+
if (limit !== undefined) args.limit = limit;
|
|
414
|
+
const result = await mcpClient.callTool("chorus_search_mentionables", args);
|
|
415
|
+
return JSON.stringify(result, null, 2);
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ChorusMcpClient } from "../mcp-client.js";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export function registerDevTools(api: any, mcpClient: ChorusMcpClient) {
|
|
5
|
+
api.registerTool({
|
|
6
|
+
name: "chorus_claim_task",
|
|
7
|
+
description: "Claim an open task (open -> assigned)",
|
|
8
|
+
parameters: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
taskUuid: { type: "string", description: "Task UUID to claim" },
|
|
12
|
+
},
|
|
13
|
+
required: ["taskUuid"],
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
},
|
|
16
|
+
async execute(_id: string, { taskUuid }: { taskUuid: string }) {
|
|
17
|
+
const result = await mcpClient.callTool("chorus_claim_task", { taskUuid });
|
|
18
|
+
return JSON.stringify(result, null, 2);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
api.registerTool({
|
|
23
|
+
name: "chorus_update_task",
|
|
24
|
+
description: "Update task status (only the assignee can operate)",
|
|
25
|
+
parameters: {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
taskUuid: { type: "string", description: "Task UUID" },
|
|
29
|
+
status: { type: "string", description: "New status: in_progress | to_verify" },
|
|
30
|
+
sessionUuid: { type: "string", description: "Session UUID for sub-agent identification" },
|
|
31
|
+
},
|
|
32
|
+
required: ["taskUuid", "status"],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
async execute(_id: string, { taskUuid, status, sessionUuid }: { taskUuid: string; status: string; sessionUuid?: string }) {
|
|
36
|
+
const args: Record<string, unknown> = { taskUuid, status };
|
|
37
|
+
if (sessionUuid) args.sessionUuid = sessionUuid;
|
|
38
|
+
const result = await mcpClient.callTool("chorus_update_task", args);
|
|
39
|
+
return JSON.stringify(result, null, 2);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
api.registerTool({
|
|
44
|
+
name: "chorus_report_work",
|
|
45
|
+
description: "Report work progress or completion on a task",
|
|
46
|
+
parameters: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
taskUuid: { type: "string", description: "Task UUID" },
|
|
50
|
+
report: { type: "string", description: "Work report content" },
|
|
51
|
+
status: { type: "string", description: "Optional: update status at the same time (in_progress | to_verify)" },
|
|
52
|
+
sessionUuid: { type: "string", description: "Session UUID for sub-agent identification" },
|
|
53
|
+
},
|
|
54
|
+
required: ["taskUuid", "report"],
|
|
55
|
+
additionalProperties: false,
|
|
56
|
+
},
|
|
57
|
+
async execute(_id: string, { taskUuid, report, status, sessionUuid }: { taskUuid: string; report: string; status?: string; sessionUuid?: string }) {
|
|
58
|
+
const args: Record<string, unknown> = { taskUuid, report };
|
|
59
|
+
if (status) args.status = status;
|
|
60
|
+
if (sessionUuid) args.sessionUuid = sessionUuid;
|
|
61
|
+
const result = await mcpClient.callTool("chorus_report_work", args);
|
|
62
|
+
return JSON.stringify(result, null, 2);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
api.registerTool({
|
|
67
|
+
name: "chorus_submit_for_verify",
|
|
68
|
+
description: "Submit task for human verification (in_progress -> to_verify)",
|
|
69
|
+
parameters: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
taskUuid: { type: "string", description: "Task UUID" },
|
|
73
|
+
summary: { type: "string", description: "Work summary" },
|
|
74
|
+
},
|
|
75
|
+
required: ["taskUuid"],
|
|
76
|
+
additionalProperties: false,
|
|
77
|
+
},
|
|
78
|
+
async execute(_id: string, { taskUuid, summary }: { taskUuid: string; summary?: string }) {
|
|
79
|
+
const args: Record<string, unknown> = { taskUuid };
|
|
80
|
+
if (summary) args.summary = summary;
|
|
81
|
+
const result = await mcpClient.callTool("chorus_submit_for_verify", args);
|
|
82
|
+
return JSON.stringify(result, null, 2);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|