@chorus-aidlc/chorus-openclaw-plugin 0.4.0 → 0.5.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.
Files changed (58) hide show
  1. package/README.md +208 -278
  2. package/dist/commands.d.ts +5 -0
  3. package/dist/commands.d.ts.map +1 -0
  4. package/dist/commands.js +147 -0
  5. package/dist/commands.js.map +1 -0
  6. package/dist/config.d.ts +38 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +57 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/event-router.d.ts +55 -0
  11. package/dist/event-router.d.ts.map +1 -0
  12. package/dist/event-router.js +157 -0
  13. package/dist/event-router.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +108 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/mcp-client.d.ts +37 -0
  19. package/dist/mcp-client.d.ts.map +1 -0
  20. package/dist/mcp-client.js +137 -0
  21. package/dist/mcp-client.js.map +1 -0
  22. package/dist/mcp-registration.d.ts +25 -0
  23. package/dist/mcp-registration.d.ts.map +1 -0
  24. package/dist/mcp-registration.js +93 -0
  25. package/dist/mcp-registration.js.map +1 -0
  26. package/dist/sse-listener.d.ts +37 -0
  27. package/dist/sse-listener.d.ts.map +1 -0
  28. package/dist/sse-listener.js +152 -0
  29. package/dist/sse-listener.js.map +1 -0
  30. package/dist/wake.d.ts +67 -0
  31. package/dist/wake.d.ts.map +1 -0
  32. package/dist/wake.js +234 -0
  33. package/dist/wake.js.map +1 -0
  34. package/openclaw.plugin.json +13 -12
  35. package/package.json +23 -5
  36. package/skills/brainstorm/SKILL.md +163 -0
  37. package/skills/chorus/SKILL.md +114 -97
  38. package/skills/develop/SKILL.md +197 -52
  39. package/skills/idea/SKILL.md +136 -150
  40. package/skills/openspec-aware/SKILL.md +425 -0
  41. package/skills/proposal/SKILL.md +162 -153
  42. package/skills/proposal-reviewer/SKILL.md +118 -0
  43. package/skills/quick-dev/SKILL.md +34 -10
  44. package/skills/review/SKILL.md +109 -35
  45. package/skills/task-reviewer/SKILL.md +113 -0
  46. package/skills/yolo/SKILL.md +501 -0
  47. package/src/commands.ts +138 -71
  48. package/src/config.ts +23 -10
  49. package/src/event-router.ts +46 -54
  50. package/src/index.ts +56 -83
  51. package/src/mcp-client.ts +17 -0
  52. package/src/mcp-registration.ts +142 -0
  53. package/src/openclaw-sdk.d.ts +95 -0
  54. package/src/wake.ts +310 -0
  55. package/src/tools/admin-tools.ts +0 -126
  56. package/src/tools/common-tools.ts +0 -575
  57. package/src/tools/dev-tools.ts +0 -105
  58. package/src/tools/pm-tools.ts +0 -411
@@ -1,411 +0,0 @@
1
- import type { ChorusMcpClient } from "../mcp-client.js";
2
-
3
- function toolResult(result: unknown) {
4
- return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], details: result };
5
- }
6
-
7
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
9
- // 1. chorus_claim_idea
10
- api.registerTool({
11
- name: "chorus_claim_idea",
12
- label: "Claim Idea",
13
- description: "Claim an open Idea for elaboration (open -> elaborating). After claiming, start elaboration or create a proposal directly.",
14
- parameters: {
15
- type: "object",
16
- properties: {
17
- ideaUuid: { type: "string", description: "UUID of the idea to claim" },
18
- },
19
- required: ["ideaUuid"],
20
- additionalProperties: false,
21
- },
22
- async execute(_id: string, { ideaUuid }: { ideaUuid: string }) {
23
- const result = await mcpClient.callTool("chorus_claim_idea", { ideaUuid });
24
- return toolResult(result);
25
- },
26
- });
27
-
28
- // 2. chorus_start_elaboration
29
- api.registerTool({
30
- name: "chorus_start_elaboration",
31
- label: "Start Elaboration",
32
- description: "Start an elaboration round for an Idea. Creates structured questions for the stakeholder to answer before proposal creation.",
33
- parameters: {
34
- type: "object",
35
- properties: {
36
- ideaUuid: { type: "string", description: "UUID of the idea" },
37
- depth: { type: "string", description: 'Elaboration depth: "minimal", "standard", or "comprehensive"' },
38
- questions: {
39
- type: "array",
40
- description: "Array of questions. Each: { id, text, category, options: [{ id, label, description? }] }",
41
- items: { type: "object" },
42
- },
43
- },
44
- required: ["ideaUuid", "depth", "questions"],
45
- additionalProperties: false,
46
- },
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- async execute(_id: string, { ideaUuid, depth, questions }: { ideaUuid: string; depth: string; questions: any[] }) {
49
- const result = await mcpClient.callTool("chorus_pm_start_elaboration", { ideaUuid, depth, questions });
50
- return toolResult(result);
51
- },
52
- });
53
-
54
- // 3. chorus_answer_elaboration
55
- api.registerTool({
56
- name: "chorus_answer_elaboration",
57
- label: "Answer Elaboration",
58
- description: "Answer elaboration questions for an Idea. Submits answers for a specific elaboration round.",
59
- parameters: {
60
- type: "object",
61
- properties: {
62
- ideaUuid: { type: "string", description: "UUID of the idea" },
63
- roundUuid: { type: "string", description: "UUID of the elaboration round" },
64
- answers: {
65
- type: "array",
66
- description: "Array of answers. Each: { questionId, selectedOptionId, customText }",
67
- items: { type: "object" },
68
- },
69
- },
70
- required: ["ideaUuid", "roundUuid", "answers"],
71
- additionalProperties: false,
72
- },
73
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
- async execute(_id: string, { ideaUuid, roundUuid, answers }: { ideaUuid: string; roundUuid: string; answers: any[] }) {
75
- const result = await mcpClient.callTool("chorus_answer_elaboration", { ideaUuid, roundUuid, answers });
76
- return toolResult(result);
77
- },
78
- });
79
-
80
- // 4. chorus_validate_elaboration
81
- api.registerTool({
82
- name: "chorus_validate_elaboration",
83
- label: "Validate Elaboration",
84
- description: "Validate answers from an elaboration round. Empty issues array = all valid, marks elaboration as resolved.",
85
- parameters: {
86
- type: "object",
87
- properties: {
88
- ideaUuid: { type: "string", description: "UUID of the idea" },
89
- roundUuid: { type: "string", description: "UUID of the elaboration round" },
90
- issues: {
91
- type: "array",
92
- description: 'Array of issues. Each: { questionId, type: "contradiction"|"ambiguity"|"incomplete", description }. Empty = valid.',
93
- items: { type: "object" },
94
- },
95
- },
96
- required: ["ideaUuid", "roundUuid", "issues"],
97
- additionalProperties: false,
98
- },
99
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
- async execute(_id: string, { ideaUuid, roundUuid, issues }: { ideaUuid: string; roundUuid: string; issues: any[] }) {
101
- const result = await mcpClient.callTool("chorus_pm_validate_elaboration", { ideaUuid, roundUuid, issues });
102
- return toolResult(result);
103
- },
104
- });
105
-
106
- // 5. chorus_create_proposal
107
- api.registerTool({
108
- name: "chorus_create_proposal",
109
- label: "Create Proposal",
110
- description: "Create an empty Proposal container. Use chorus_add_document_draft and chorus_add_task_draft to populate it afterwards.",
111
- parameters: {
112
- type: "object",
113
- properties: {
114
- projectUuid: { type: "string", description: "Project UUID" },
115
- title: { type: "string", description: "Proposal title" },
116
- inputType: { type: "string", description: 'Input source type: "idea" or "document"' },
117
- inputUuids: { type: "array", description: "Array of input UUIDs", items: { type: "string" } },
118
- description: { type: "string", description: "Proposal description" },
119
- },
120
- required: ["projectUuid", "title", "inputType", "inputUuids"],
121
- additionalProperties: false,
122
- },
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- async execute(_id: string, { projectUuid, title, inputType, inputUuids, description }: any) {
125
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
- const args: Record<string, any> = { projectUuid, title, inputType, inputUuids };
127
- if (description !== undefined) args.description = description;
128
- const result = await mcpClient.callTool("chorus_pm_create_proposal", args);
129
- return toolResult(result);
130
- },
131
- });
132
-
133
- // 6. chorus_add_document_draft
134
- api.registerTool({
135
- name: "chorus_add_document_draft",
136
- label: "Add Doc Draft",
137
- description: "Add a document draft to a pending Proposal container.",
138
- parameters: {
139
- type: "object",
140
- properties: {
141
- proposalUuid: { type: "string", description: "Proposal UUID" },
142
- type: { type: "string", description: "Document type (prd, tech_design, adr, spec, guide)" },
143
- title: { type: "string", description: "Document title" },
144
- content: { type: "string", description: "Document content (Markdown)" },
145
- },
146
- required: ["proposalUuid", "type", "title", "content"],
147
- additionalProperties: false,
148
- },
149
- async execute(_id: string, { proposalUuid, type, title, content }: { proposalUuid: string; type: string; title: string; content: string }) {
150
- const result = await mcpClient.callTool("chorus_pm_add_document_draft", { proposalUuid, type, title, content });
151
- return toolResult(result);
152
- },
153
- });
154
-
155
- // 7. chorus_add_task_draft
156
- api.registerTool({
157
- name: "chorus_add_task_draft",
158
- label: "Add Task Draft",
159
- description: "Add a task draft to a pending Proposal container.",
160
- parameters: {
161
- type: "object",
162
- properties: {
163
- proposalUuid: { type: "string", description: "Proposal UUID" },
164
- title: { type: "string", description: "Task title" },
165
- description: { type: "string", description: "Task description" },
166
- priority: { type: "string", description: 'Priority: "low", "medium", or "high"' },
167
- storyPoints: { type: "number", description: "Effort estimate in agent hours" },
168
- acceptanceCriteriaItems: { type: "array", description: "Structured acceptance criteria: [{ description, required? }]", items: { type: "object", properties: { description: { type: "string" }, required: { type: "boolean" } }, required: ["description"] } },
169
- dependsOnDraftUuids: { type: "array", description: "Dependent task draft UUIDs", items: { type: "string" } },
170
- },
171
- required: ["proposalUuid", "title"],
172
- additionalProperties: false,
173
- },
174
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
- async execute(_id: string, { proposalUuid, title, description, priority, storyPoints, acceptanceCriteriaItems, dependsOnDraftUuids }: any) {
176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
- const args: Record<string, any> = { proposalUuid, title };
178
- if (description !== undefined) args.description = description;
179
- if (priority !== undefined) args.priority = priority;
180
- if (storyPoints !== undefined) args.storyPoints = storyPoints;
181
- if (acceptanceCriteriaItems !== undefined) args.acceptanceCriteriaItems = acceptanceCriteriaItems;
182
- if (dependsOnDraftUuids !== undefined) args.dependsOnDraftUuids = dependsOnDraftUuids;
183
- const result = await mcpClient.callTool("chorus_pm_add_task_draft", args);
184
- return toolResult(result);
185
- },
186
- });
187
-
188
- // 8. chorus_get_proposal — View full proposal with all drafts
189
- api.registerTool({
190
- name: "chorus_get_proposal",
191
- label: "Get Proposal",
192
- description: "Get detailed information for a Proposal, including all document drafts and task drafts with their UUIDs. Use this to inspect proposal contents before modifying or submitting.",
193
- parameters: {
194
- type: "object",
195
- properties: {
196
- proposalUuid: { type: "string", description: "Proposal UUID" },
197
- },
198
- required: ["proposalUuid"],
199
- additionalProperties: false,
200
- },
201
- async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
202
- const result = await mcpClient.callTool("chorus_get_proposal", { proposalUuid });
203
- return toolResult(result);
204
- },
205
- });
206
-
207
- // 9. chorus_update_document_draft — Modify an existing document draft
208
- api.registerTool({
209
- name: "chorus_update_document_draft",
210
- label: "Update Doc Draft",
211
- description: "Update a document draft in a Proposal. Can change title, type, or content.",
212
- parameters: {
213
- type: "object",
214
- properties: {
215
- proposalUuid: { type: "string", description: "Proposal UUID" },
216
- draftUuid: { type: "string", description: "Document draft UUID to update" },
217
- title: { type: "string", description: "New document title" },
218
- type: { type: "string", description: "New document type (prd, tech_design, adr, spec, guide)" },
219
- content: { type: "string", description: "New document content (Markdown)" },
220
- },
221
- required: ["proposalUuid", "draftUuid"],
222
- additionalProperties: false,
223
- },
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
- async execute(_id: string, { proposalUuid, draftUuid, title, type, content }: any) {
226
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
- const args: Record<string, any> = { proposalUuid, draftUuid };
228
- if (title !== undefined) args.title = title;
229
- if (type !== undefined) args.type = type;
230
- if (content !== undefined) args.content = content;
231
- const result = await mcpClient.callTool("chorus_pm_update_document_draft", args);
232
- return toolResult(result);
233
- },
234
- });
235
-
236
- // 10. chorus_update_task_draft — Modify an existing task draft (including dependencies)
237
- api.registerTool({
238
- name: "chorus_update_task_draft",
239
- label: "Update Task Draft",
240
- description: "Update a task draft in a Proposal. Use this to fix validation issues, add dependencies (dependsOnDraftUuids), change priority, etc.",
241
- parameters: {
242
- type: "object",
243
- properties: {
244
- proposalUuid: { type: "string", description: "Proposal UUID" },
245
- draftUuid: { type: "string", description: "Task draft UUID to update" },
246
- title: { type: "string", description: "New task title" },
247
- description: { type: "string", description: "New task description" },
248
- priority: { type: "string", description: 'Priority: "low", "medium", or "high"' },
249
- storyPoints: { type: "number", description: "Effort estimate in agent hours" },
250
- acceptanceCriteriaItems: { type: "array", description: "Structured acceptance criteria: [{ description, required? }]", items: { type: "object", properties: { description: { type: "string" }, required: { type: "boolean" } }, required: ["description"] } },
251
- dependsOnDraftUuids: { type: "array", description: "Task draft UUIDs this task depends on (sets execution order)", items: { type: "string" } },
252
- },
253
- required: ["proposalUuid", "draftUuid"],
254
- additionalProperties: false,
255
- },
256
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
- async execute(_id: string, { proposalUuid, draftUuid, title, description, priority, storyPoints, acceptanceCriteriaItems, dependsOnDraftUuids }: any) {
258
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
- const args: Record<string, any> = { proposalUuid, draftUuid };
260
- if (title !== undefined) args.title = title;
261
- if (description !== undefined) args.description = description;
262
- if (priority !== undefined) args.priority = priority;
263
- if (storyPoints !== undefined) args.storyPoints = storyPoints;
264
- if (acceptanceCriteriaItems !== undefined) args.acceptanceCriteriaItems = acceptanceCriteriaItems;
265
- if (dependsOnDraftUuids !== undefined) args.dependsOnDraftUuids = dependsOnDraftUuids;
266
- const result = await mcpClient.callTool("chorus_pm_update_task_draft", args);
267
- return toolResult(result);
268
- },
269
- });
270
-
271
- // 11. chorus_remove_document_draft
272
- api.registerTool({
273
- name: "chorus_remove_document_draft",
274
- label: "Remove Doc Draft",
275
- description: "Remove a document draft from a Proposal.",
276
- parameters: {
277
- type: "object",
278
- properties: {
279
- proposalUuid: { type: "string", description: "Proposal UUID" },
280
- draftUuid: { type: "string", description: "Document draft UUID to remove" },
281
- },
282
- required: ["proposalUuid", "draftUuid"],
283
- additionalProperties: false,
284
- },
285
- async execute(_id: string, { proposalUuid, draftUuid }: { proposalUuid: string; draftUuid: string }) {
286
- const result = await mcpClient.callTool("chorus_pm_remove_document_draft", { proposalUuid, draftUuid });
287
- return toolResult(result);
288
- },
289
- });
290
-
291
- // 12. chorus_remove_task_draft
292
- api.registerTool({
293
- name: "chorus_remove_task_draft",
294
- label: "Remove Task Draft",
295
- description: "Remove a task draft from a Proposal.",
296
- parameters: {
297
- type: "object",
298
- properties: {
299
- proposalUuid: { type: "string", description: "Proposal UUID" },
300
- draftUuid: { type: "string", description: "Task draft UUID to remove" },
301
- },
302
- required: ["proposalUuid", "draftUuid"],
303
- additionalProperties: false,
304
- },
305
- async execute(_id: string, { proposalUuid, draftUuid }: { proposalUuid: string; draftUuid: string }) {
306
- const result = await mcpClient.callTool("chorus_pm_remove_task_draft", { proposalUuid, draftUuid });
307
- return toolResult(result);
308
- },
309
- });
310
-
311
- // 13. chorus_validate_proposal
312
- api.registerTool({
313
- name: "chorus_validate_proposal",
314
- label: "Validate Proposal",
315
- description: "Validate a Proposal's completeness before submission. Returns errors (block submit), warnings, and info. ALWAYS call this before chorus_submit_proposal. If errors exist, use chorus_update_task_draft / chorus_update_document_draft to fix them, then validate again.",
316
- parameters: {
317
- type: "object",
318
- properties: {
319
- proposalUuid: { type: "string", description: "Proposal UUID to validate" },
320
- },
321
- required: ["proposalUuid"],
322
- additionalProperties: false,
323
- },
324
- async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
325
- const result = await mcpClient.callTool("chorus_pm_validate_proposal", { proposalUuid });
326
- return toolResult(result);
327
- },
328
- });
329
-
330
- // 9. chorus_submit_proposal
331
- api.registerTool({
332
- name: "chorus_submit_proposal",
333
- label: "Submit Proposal",
334
- description: "Submit a Proposal for approval (draft -> pending). Requires all input Ideas to have elaboration resolved.",
335
- parameters: {
336
- type: "object",
337
- properties: {
338
- proposalUuid: { type: "string", description: "Proposal UUID to submit" },
339
- },
340
- required: ["proposalUuid"],
341
- additionalProperties: false,
342
- },
343
- async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
344
- const result = await mcpClient.callTool("chorus_pm_submit_proposal", { proposalUuid });
345
- return toolResult(result);
346
- },
347
- });
348
-
349
- // 15. chorus_pm_assign_task
350
- api.registerTool({
351
- name: "chorus_pm_assign_task",
352
- label: "Assign Task",
353
- description: "Assign a task to a specified Developer Agent. The task must be in open or assigned status. Use chorus_search_mentionables to find the agent UUID.",
354
- parameters: {
355
- type: "object",
356
- properties: {
357
- taskUuid: { type: "string", description: "Task UUID" },
358
- agentUuid: { type: "string", description: "Target Developer Agent UUID" },
359
- },
360
- required: ["taskUuid", "agentUuid"],
361
- additionalProperties: false,
362
- },
363
- async execute(_id: string, { taskUuid, agentUuid }: { taskUuid: string; agentUuid: string }) {
364
- const result = await mcpClient.callTool("chorus_pm_assign_task", { taskUuid, agentUuid });
365
- return toolResult(result);
366
- },
367
- });
368
-
369
- // 16. chorus_move_idea
370
- api.registerTool({
371
- name: "chorus_move_idea",
372
- label: "Move Idea",
373
- description: "Move an Idea to a different project within the same company. Also moves linked draft/pending Proposals.",
374
- parameters: {
375
- type: "object",
376
- properties: {
377
- ideaUuid: { type: "string", description: "UUID of the idea to move" },
378
- targetProjectUuid: { type: "string", description: "UUID of the target project" },
379
- },
380
- required: ["ideaUuid", "targetProjectUuid"],
381
- additionalProperties: false,
382
- },
383
- async execute(_id: string, { ideaUuid, targetProjectUuid }: { ideaUuid: string; targetProjectUuid: string }) {
384
- const result = await mcpClient.callTool("chorus_move_idea", { ideaUuid, targetProjectUuid });
385
- return toolResult(result);
386
- },
387
- });
388
-
389
- // 17. chorus_pm_create_idea
390
- api.registerTool({
391
- name: "chorus_pm_create_idea",
392
- label: "Create Idea",
393
- description: "Create a new Idea in a project. Use this when you discover a requirement, want to propose work, or record a user request.",
394
- parameters: {
395
- type: "object",
396
- properties: {
397
- projectUuid: { type: "string", description: "Project UUID" },
398
- title: { type: "string", description: "Idea title" },
399
- content: { type: "string", description: "Idea detailed description" },
400
- },
401
- required: ["projectUuid", "title"],
402
- additionalProperties: false,
403
- },
404
- async execute(_id: string, { projectUuid, title, content }: { projectUuid: string; title: string; content?: string }) {
405
- const args: Record<string, unknown> = { projectUuid, title };
406
- if (content) args.content = content;
407
- const result = await mcpClient.callTool("chorus_pm_create_idea", args);
408
- return toolResult(result);
409
- },
410
- });
411
- }