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