@chorus-aidlc/chorus-openclaw-plugin 0.3.1 → 0.4.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.
@@ -0,0 +1,282 @@
1
+ ---
2
+ name: review
3
+ description: Chorus Review workflow — approve/reject proposals, verify tasks, and manage governance.
4
+ metadata:
5
+ openclaw:
6
+ emoji: "✅"
7
+ ---
8
+
9
+ # Review Skill
10
+
11
+ This skill covers the **Review** stage of the AI-DLC workflow: approving or rejecting Proposals, verifying completed Tasks, and managing overall project governance as an Admin Agent.
12
+
13
+ ---
14
+
15
+ ## Overview
16
+
17
+ Admin Agent has **full access to all Chorus operations**. You are the **human proxy role** — acting on behalf of the project owner to ensure quality and manage the AI-DLC lifecycle.
18
+
19
+ Key responsibilities:
20
+ - **Proposal review** — approve or reject Proposals submitted by PM Agents (see `/proposal`)
21
+ - **Task verification** — verify or reopen Tasks submitted by Developer Agents (see `/develop`)
22
+ - **Project governance** — create projects, manage groups, organize work
23
+
24
+ ---
25
+
26
+ ## Tools
27
+
28
+ **Admin-Exclusive:**
29
+
30
+ | Tool | Purpose |
31
+ |------|---------|
32
+ | `chorus_admin_create_project` | Create a new project (optional `groupUuid` for group assignment) |
33
+ | `chorus_admin_create_project_group` | Create a new project group for organizing projects |
34
+ | `chorus_admin_approve_proposal` | Approve proposal (materializes documents + tasks) |
35
+ | `chorus_admin_verify_task` | Verify completed task (to_verify -> done). Blocked if required AC not all passed. |
36
+ | `chorus_mark_acceptance_criteria` | Mark acceptance criteria as passed/failed during verification (batch) |
37
+
38
+ **All PM tools** (`chorus_pm_*`, `chorus_*_idea`) and **all Developer tools** (`chorus_claim_task`, `chorus_report_work`, etc.) are also available to Admin.
39
+
40
+ **Shared tools** (checkin, query, comment, search, notifications): see `/chorus`
41
+
42
+ ---
43
+
44
+ ## SSE Wake Events
45
+
46
+ The OpenClaw plugin listens for SSE events relevant to admin review:
47
+
48
+ | SSE Event | Trigger | Agent Action |
49
+ |-----------|---------|--------------|
50
+ | `task_assigned` | A task is assigned to you | Wake and review/start work |
51
+ | `mentioned` | You are @mentioned in a comment | Wake and respond |
52
+ | `proposal_approved` / `proposal_rejected` | Proposal status changed | Informational — check new tasks or feedback |
53
+
54
+ When tasks are submitted for verification or proposals are submitted for review, the admin agent is woken to process them.
55
+
56
+ ---
57
+
58
+ ## Workflow
59
+
60
+ ### Step 1: Check In
61
+
62
+ ```
63
+ chorus_checkin()
64
+ ```
65
+
66
+ Pay attention to:
67
+ - Pending proposal count (items awaiting approval)
68
+ - Tasks in `to_verify` status (work awaiting review)
69
+ - Overall project health
70
+
71
+ ### Step 2: Triage
72
+
73
+ Check what needs your attention:
74
+
75
+ ```
76
+ # Pending proposals
77
+ chorus_get_proposals({ projectUuid: "<project-uuid>", status: "pending" })
78
+
79
+ # Tasks awaiting verification
80
+ chorus_list_tasks({ projectUuid: "<project-uuid>", status: "to_verify" })
81
+
82
+ # Recent activity
83
+ chorus_get_activity({ projectUuid: "<project-uuid>" })
84
+ ```
85
+
86
+ Prioritize: **Proposals first** (they unblock PM and Developer work), then task verifications.
87
+
88
+ ### Workflow A: Proposal Review
89
+
90
+ #### A1: Read the Proposal
91
+
92
+ ```
93
+ chorus_get_proposal({ proposalUuid: "<proposal-uuid>" })
94
+ ```
95
+
96
+ This returns: title, description, input ideas, **document drafts** (PRD, tech design), **task drafts** (with descriptions and acceptance criteria).
97
+
98
+ #### A2: Quality Checklist
99
+
100
+ **Documents:**
101
+ - [ ] PRD clearly describes the *what* and *why*
102
+ - [ ] Requirements are specific and testable
103
+ - [ ] Tech design is feasible and follows project conventions
104
+ - [ ] No missing edge cases or security considerations
105
+
106
+ **Tasks:**
107
+ - [ ] Tasks cover all requirements in the PRD
108
+ - [ ] Each task has clear acceptance criteria
109
+ - [ ] Tasks are appropriately sized (1-8 story points)
110
+ - [ ] Task descriptions have enough context for a developer agent
111
+ - [ ] Priority is set correctly
112
+
113
+ **Overall:**
114
+ - [ ] Proposal aligns with the original idea(s)
115
+ - [ ] No scope creep beyond what was requested
116
+ - [ ] Implementation approach is reasonable
117
+
118
+ #### A3: Read Comments
119
+
120
+ ```
121
+ chorus_get_comments({ targetType: "proposal", targetUuid: "<proposal-uuid>" })
122
+ ```
123
+
124
+ #### A4: Approve or Reject
125
+
126
+ **Approve:**
127
+
128
+ ```
129
+ chorus_admin_approve_proposal({
130
+ proposalUuid: "<proposal-uuid>",
131
+ reviewNote: "Approved. Good breakdown of tasks."
132
+ })
133
+ ```
134
+
135
+ The response includes `materializedTasks` and `materializedDocuments` — use them to immediately assign tasks or reference documents.
136
+
137
+ When approved:
138
+ - Document drafts become real Documents
139
+ - Task drafts become real Tasks (status: `open`)
140
+
141
+ **Reject:**
142
+
143
+ Rejection is done by adding a comment with specific feedback. The PM agent will see the comment and can revise the proposal.
144
+
145
+ ```
146
+ chorus_add_comment({
147
+ targetType: "proposal",
148
+ targetUuid: "<proposal-uuid>",
149
+ content: "Rejecting — specific feedback:\n1. Add error scenarios to PRD\n2. Task 3 AC should include performance benchmarks"
150
+ })
151
+ ```
152
+
153
+ ### Workflow B: Task Verification
154
+
155
+ #### B1: Review the Submitted Task
156
+
157
+ ```
158
+ chorus_get_task({ taskUuid: "<task-uuid>" })
159
+ ```
160
+
161
+ Check: developer's work summary, acceptance criteria, self-check results (devStatus and devEvidence on each criterion).
162
+
163
+ #### B2: Read Comments and Work Reports
164
+
165
+ ```
166
+ chorus_get_comments({ targetType: "task", targetUuid: "<task-uuid>" })
167
+ ```
168
+
169
+ Work reports are recorded as comments — look for implementation details, files changed, commits, and PRs.
170
+
171
+ #### B3: Mark Acceptance Criteria
172
+
173
+ Review and mark each criterion:
174
+
175
+ ```
176
+ chorus_mark_acceptance_criteria({
177
+ taskUuid: "<task-uuid>",
178
+ criteria: [
179
+ { uuid: "<criterion-uuid>", status: "passed" },
180
+ { uuid: "<criterion-uuid>", status: "passed" },
181
+ { uuid: "<criterion-uuid>", status: "failed", evidence: "Missing edge case handling" }
182
+ ]
183
+ })
184
+ ```
185
+
186
+ #### B4: Verify or Reopen
187
+
188
+ **Verify (all required AC passed):**
189
+
190
+ ```
191
+ chorus_admin_verify_task({ taskUuid: "<task-uuid>" })
192
+ ```
193
+
194
+ This moves the task to `done`. **Important:** verifying may unblock downstream tasks. Check:
195
+
196
+ ```
197
+ chorus_get_unblocked_tasks({ projectUuid: "<project-uuid>" })
198
+ ```
199
+
200
+ If new tasks are unblocked, assign them or notify developers.
201
+
202
+ **Request rework:**
203
+
204
+ If the task needs fixes, add a comment with specific feedback:
205
+
206
+ ```
207
+ chorus_add_comment({
208
+ targetType: "task",
209
+ targetUuid: "<task-uuid>",
210
+ content: "Needs rework: Missing error handling for user-not-found edge case."
211
+ })
212
+ ```
213
+
214
+ ### Workflow C: Project Management
215
+
216
+ #### Create Project
217
+
218
+ ```
219
+ chorus_get_project_groups() # List available groups first
220
+ chorus_admin_create_project({
221
+ name: "My Project",
222
+ description: "Project goals...",
223
+ groupUuid: "<optional-group-uuid>"
224
+ })
225
+ ```
226
+
227
+ #### Manage Project Groups
228
+
229
+ ```
230
+ chorus_admin_create_project_group({ name: "Mobile Apps", description: "All mobile projects" })
231
+ ```
232
+
233
+ #### Assign Tasks
234
+
235
+ Use the PM tool to assign tasks to specific agents:
236
+
237
+ ```
238
+ chorus_pm_assign_task({ taskUuid: "<task-uuid>", assigneeUuid: "<agent-uuid>", assigneeType: "agent" })
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Daily Admin Routine
244
+
245
+ 1. **Check in** — `chorus_checkin()`
246
+ 2. **Review activity** — `chorus_get_activity()` for recent events
247
+ 3. **Process proposals** — Review and approve/reject pending proposals
248
+ 4. **Verify tasks** — Review and verify tasks in `to_verify`
249
+ 5. **Create new ideas** — If the human has new requirements
250
+ 6. **Check project health** — Stale tasks? Blocked items? Orphaned ideas?
251
+
252
+ ---
253
+
254
+ ## Tips
255
+
256
+ - **Review thoroughly** — Don't rubber-stamp proposals; check quality
257
+ - **Give actionable feedback** — When requesting changes, explain specifically what to fix
258
+ - **Verify against criteria** — Check acceptance criteria, not just the summary
259
+ - **Unblock the team** — Prioritize proposal reviews to keep PM and Developer work flowing
260
+ - **Document decisions** — Use comments to explain approval/rejection reasoning
261
+ - **Check downstream** — After verifying a task, check `chorus_get_unblocked_tasks` to see what was unblocked
262
+
263
+ ---
264
+
265
+ ## Governance Principles
266
+
267
+ 1. **Quality over speed** — A rejected proposal now saves rework later
268
+ 2. **Actionable feedback** — Every rejection should include specific fixes
269
+ 3. **Criteria-based verification** — Verify against acceptance criteria, not just subjective impression
270
+ 4. **Scope discipline** — Keep work focused on what was planned
271
+ 5. **Unblock others** — Your reviews are the bottleneck; prioritize them
272
+ 6. **Preserve history** — Comments and decisions help future agents understand reasoning
273
+ 7. **Document reasoning** — Future agents will read your comments to understand decisions
274
+
275
+ ---
276
+
277
+ ## Next
278
+
279
+ - For platform overview and shared tools, see `/chorus`
280
+ - For Idea elaboration (before proposals), see `/idea`
281
+ - For Proposal creation (what you're reviewing), see `/proposal`
282
+ - For Developer workflow (what you're verifying), see `/develop`
package/src/commands.ts CHANGED
@@ -46,11 +46,28 @@ interface AssignmentsResponse {
46
46
 
47
47
  // ===== Formatting helpers =====
48
48
 
49
+ const PLUGIN_SKILLS = [
50
+ { name: "chorus", emoji: "🎵", description: "Platform overview, tools, setup, and workflow routing" },
51
+ { name: "idea", emoji: "💡", description: "Claim ideas, run elaboration, prepare for proposal" },
52
+ { name: "proposal", emoji: "📋", description: "Create proposals with document & task drafts, manage DAG" },
53
+ { name: "develop", emoji: "🔨", description: "Claim tasks, report work, submit for verification" },
54
+ { name: "quick-dev", emoji: "⚡", description: "Skip Idea→Proposal, create tasks directly" },
55
+ { name: "review", emoji: "✅", description: "Approve/reject proposals, verify tasks, governance" },
56
+ ] as const;
57
+
58
+ function formatSkillsList(): string {
59
+ const lines = PLUGIN_SKILLS.map(
60
+ (s) => ` ${s.emoji} ${s.name.padEnd(12)} ${s.description}`
61
+ );
62
+ return `Chorus skills (${PLUGIN_SKILLS.length}):\n${lines.join("\n")}\n\nUse: /chorus:<skill-name> (e.g. /chorus:idea)`;
63
+ }
64
+
49
65
  function formatStatus(checkin: CheckinResponse, connectionStatus: string): string {
50
66
  const lines: string[] = [
51
67
  `Connection: ${connectionStatus}`,
52
68
  `Assignments: ${checkin?.pending?.ideasCount ?? 0} ideas, ${checkin?.pending?.tasksCount ?? 0} tasks`,
53
69
  `Notifications: ${checkin?.notifications?.unreadCount ?? 0} unread`,
70
+ `Skills: ${PLUGIN_SKILLS.map((s) => s.name).join(", ")}`,
54
71
  ];
55
72
  return lines.join("\n");
56
73
  }
@@ -83,6 +100,7 @@ const HELP_TEXT = [
83
100
  " /chorus status Same as above",
84
101
  " /chorus tasks List assigned tasks",
85
102
  " /chorus ideas List assigned ideas",
103
+ " /chorus skills List available Chorus skills",
86
104
  ].join("\n");
87
105
 
88
106
  // ===== Registration =====
@@ -121,6 +139,11 @@ export function registerChorusCommands(
121
139
  }
122
140
  }
123
141
 
142
+ // /chorus skills
143
+ if (sub === "skills") {
144
+ return { text: formatSkillsList() };
145
+ }
146
+
124
147
  // /chorus ideas
125
148
  if (sub === "ideas") {
126
149
  try {
@@ -1,9 +1,14 @@
1
1
  import type { ChorusMcpClient } from "../mcp-client.js";
2
2
 
3
+ function toolResult(result: unknown) {
4
+ return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], details: result };
5
+ }
6
+
3
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
8
  export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
5
9
  api.registerTool({
6
10
  name: "chorus_admin_create_project",
11
+ label: "Create Project",
7
12
  description: "Create a new project. Call chorus_get_project_groups first to find the right groupUuid.",
8
13
  parameters: {
9
14
  type: "object",
@@ -20,12 +25,13 @@ export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
20
25
  if (description) args.description = description;
21
26
  if (groupUuid) args.groupUuid = groupUuid;
22
27
  const result = await mcpClient.callTool("chorus_admin_create_project", args);
23
- return JSON.stringify(result, null, 2);
28
+ return toolResult(result);
24
29
  },
25
30
  });
26
31
 
27
32
  api.registerTool({
28
33
  name: "chorus_admin_create_project_group",
34
+ label: "Create Group",
29
35
  description: "Create a new project group for organizing projects.",
30
36
  parameters: {
31
37
  type: "object",
@@ -40,12 +46,13 @@ export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
40
46
  const args: Record<string, unknown> = { name };
41
47
  if (description) args.description = description;
42
48
  const result = await mcpClient.callTool("chorus_admin_create_project_group", args);
43
- return JSON.stringify(result, null, 2);
49
+ return toolResult(result);
44
50
  },
45
51
  });
46
52
 
47
53
  api.registerTool({
48
54
  name: "chorus_admin_approve_proposal",
55
+ label: "Approve Proposal",
49
56
  description:
50
57
  "Approve a Proposal (Admin exclusive). On approval, documentDrafts and taskDrafts are automatically materialized into real Document and Task entities — materialized Tasks can then be claimed and executed by agents. " +
51
58
  "⚠️ This action is irreversible — unless there is a special reason, you MUST obtain explicit human approval before calling this tool.",
@@ -62,12 +69,13 @@ export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
62
69
  const args: Record<string, unknown> = { proposalUuid };
63
70
  if (reviewNote) args.reviewNote = reviewNote;
64
71
  const result = await mcpClient.callTool("chorus_admin_approve_proposal", args);
65
- return JSON.stringify(result, null, 2);
72
+ return toolResult(result);
66
73
  },
67
74
  });
68
75
 
69
76
  api.registerTool({
70
77
  name: "chorus_admin_verify_task",
78
+ label: "Verify Task",
71
79
  description:
72
80
  "Verify a Task (to_verify → done, Admin exclusive). Marks a task as completed after verification. Downstream tasks that depend on this task will only be unblocked after it is verified. " +
73
81
  "⚠️ This action is irreversible — unless there is a special reason, you MUST obtain explicit human approval before calling this tool.",
@@ -81,12 +89,13 @@ export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
81
89
  },
82
90
  async execute(_id: string, { taskUuid }: { taskUuid: string }) {
83
91
  const result = await mcpClient.callTool("chorus_admin_verify_task", { taskUuid });
84
- return JSON.stringify(result, null, 2);
92
+ return toolResult(result);
85
93
  },
86
94
  });
87
95
 
88
96
  api.registerTool({
89
97
  name: "chorus_mark_acceptance_criteria",
98
+ label: "Mark AC",
90
99
  description: "Mark acceptance criteria as passed or failed (admin verification). Blocked criteria prevent task from being verified (to_verify -> done).",
91
100
  parameters: {
92
101
  type: "object",
@@ -111,7 +120,7 @@ export function registerAdminTools(api: any, mcpClient: ChorusMcpClient) {
111
120
  },
112
121
  async execute(_id: string, { taskUuid, criteria }: { taskUuid: string; criteria: Array<{ uuid: string; status: string; evidence?: string }> }) {
113
122
  const result = await mcpClient.callTool("chorus_mark_acceptance_criteria", { taskUuid, criteria });
114
- return JSON.stringify(result, null, 2);
123
+ return toolResult(result);
115
124
  },
116
125
  });
117
126
  }