@cliangdev/conductor 0.2.1 → 0.2.2
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 +3 -1
- package/assets/claude/commands/conductor/fix.md +328 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,8 @@ The platform is built around Claude Code. You write PRDs with AI, your team revi
|
|
|
19
19
|
2. Team reviews → Conductor web app — comment, approve, request changes
|
|
20
20
|
3. Implement → /conductor:implement in Claude Code
|
|
21
21
|
4. PR opens → Claude commits, pushes, and creates the pull request
|
|
22
|
-
5.
|
|
22
|
+
5. Fix & iterate → /conductor:fix — address review feedback on the open PR
|
|
23
|
+
6. Merge → Issue closes automatically
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
Agents do the execution. Humans set the intent and sign off.
|
|
@@ -48,6 +49,7 @@ Then open Claude Code in your project and run `/conductor:prd` to create your fi
|
|
|
48
49
|
|---------|-------------|
|
|
49
50
|
| `/conductor:prd` | Guides you through writing a PRD with AI — discovery, research, structured output |
|
|
50
51
|
| `/conductor:implement` | Takes an approved PRD and implements it — task breakdown, parallel subagents, PR creation |
|
|
52
|
+
| `/conductor:fix` | Fixes bugs and review feedback on an open PR — structured intake, investigation, build validation, and push |
|
|
51
53
|
|
|
52
54
|
These commands are installed automatically when you run `conductor init` (project-level) or during global install (user-level, to `~/.claude/`).
|
|
53
55
|
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: conductor:fix
|
|
3
|
+
description: Fix a bug found during PR review — structured intake, root cause investigation, full build validation, and push to the existing PR branch. Transitions the Conductor issue to IN_PROGRESS at start and back to CODE_REVIEW after push.
|
|
4
|
+
allowed-tools: mcp__conductor__*, AskUserQuestion, Read, Write, Edit, Glob, Grep, Bash, ScheduleWakeup
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /conductor:fix
|
|
8
|
+
|
|
9
|
+
You are the Conductor fix orchestrator. Your job is to guide an engineer through fixing a bug discovered during PR review — structured intake, root cause investigation, full local build validation, and a clean push to the existing PR branch.
|
|
10
|
+
|
|
11
|
+
## Trigger
|
|
12
|
+
|
|
13
|
+
This skill runs when the user invokes `/conductor:fix` (no arguments — the PR branch is auto-detected).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Step 1 — Pre-Flight Checks
|
|
18
|
+
|
|
19
|
+
Detect the active Conductor PR branch and verify the working tree is clean before any investigation begins.
|
|
20
|
+
|
|
21
|
+
1. **Get current branch**: run `git branch --show-current` → capture as `branch`
|
|
22
|
+
|
|
23
|
+
2. **Parse displayId**: match `branch` against `^feat/([A-Z]+-\d+)$`
|
|
24
|
+
- If it does **not** match, halt immediately:
|
|
25
|
+
> Error: current branch `{branch}` does not match `feat/{displayId}`. Checkout a `conductor:implement` branch and retry.
|
|
26
|
+
- Do **not** edit any files after this error.
|
|
27
|
+
|
|
28
|
+
3. **Find open PR**: run:
|
|
29
|
+
```bash
|
|
30
|
+
gh pr list --head {branch} --json number,url,state --jq '.[] | select(.state=="OPEN")'
|
|
31
|
+
```
|
|
32
|
+
- If result is empty → halt:
|
|
33
|
+
> Error: no open PR found for branch `{branch}`. Open a PR (or run `/conductor:implement`) and retry.
|
|
34
|
+
|
|
35
|
+
Capture `prNumber` (`.number`) and `prUrl` (`.url`).
|
|
36
|
+
|
|
37
|
+
4. **Resolve issueId**: call `list_issues` and find the issue where `displayId` matches the parsed value. Capture `issueId` (UUID).
|
|
38
|
+
- If no match → halt:
|
|
39
|
+
> Error: no Conductor issue found with displayId `{displayId}`. Verify the project config and retry.
|
|
40
|
+
|
|
41
|
+
5. **Load issue**: call `get_issue(issueId)` — capture `absolutePath` (the issue directory on disk, used for all subsequent Read/Write/Edit calls) and `status`.
|
|
42
|
+
|
|
43
|
+
6. **Check working tree**: run `git status --porcelain`
|
|
44
|
+
- If output is non-empty, use AskUserQuestion:
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"questions": [{
|
|
48
|
+
"question": "Uncommitted changes detected. How would you like to handle them?",
|
|
49
|
+
"header": "Dirty Working Tree",
|
|
50
|
+
"options": [
|
|
51
|
+
{"label": "Stash", "description": "git stash — restore after fix session"},
|
|
52
|
+
{"label": "Commit as WIP", "description": "git add -A && commit as wip: before conductor:fix"},
|
|
53
|
+
{"label": "Abort", "description": "Stop here, no changes made"}
|
|
54
|
+
],
|
|
55
|
+
"multiSelect": false
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
- **Stash**: `git stash`
|
|
60
|
+
- **Commit as WIP**: `git add -A && git commit -m "wip: before conductor:fix"`
|
|
61
|
+
- **Abort**: stop here
|
|
62
|
+
|
|
63
|
+
7. Print confirmation:
|
|
64
|
+
```
|
|
65
|
+
✓ Branch: {branch}
|
|
66
|
+
✓ PR #{prNumber}: {prUrl}
|
|
67
|
+
✓ Issue: {displayId} (resolved)
|
|
68
|
+
✓ Working tree clean
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Step 2 — Issue Status Check
|
|
74
|
+
|
|
75
|
+
Transition the Conductor issue to `IN_PROGRESS` before investigation begins.
|
|
76
|
+
|
|
77
|
+
Based on the `status` captured in Step 1:
|
|
78
|
+
|
|
79
|
+
| Current status | Action |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `CODE_REVIEW` | Call `set_issue_status(issueId, "IN_PROGRESS")` |
|
|
82
|
+
| `IN_PROGRESS` | Already correct — no-op, proceed |
|
|
83
|
+
| Any other status | Warn and ask user |
|
|
84
|
+
|
|
85
|
+
For any other status, use AskUserQuestion:
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"questions": [{
|
|
89
|
+
"question": "Issue {displayId} is currently `{status}` — not the expected `CODE_REVIEW`. Continue anyway?",
|
|
90
|
+
"header": "Unexpected Issue Status",
|
|
91
|
+
"options": [
|
|
92
|
+
{"label": "Continue anyway", "description": "Proceed with the fix session"},
|
|
93
|
+
{"label": "Abort", "description": "Stop here without changes"}
|
|
94
|
+
],
|
|
95
|
+
"multiSelect": false
|
|
96
|
+
}]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
After calling `set_issue_status`, check the response for a `warning` field. If present:
|
|
101
|
+
> ⚠️ Status update failed (queued): {warning}
|
|
102
|
+
> Run `conductor start` to drain the sync queue, then verify the status in the UI before continuing.
|
|
103
|
+
|
|
104
|
+
Use AskUserQuestion with options: **Continue anyway** / **Abort**.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Step 3 — Structured Bug Intake
|
|
109
|
+
|
|
110
|
+
Capture the bug report through three sequential AskUserQuestion prompts before touching any code.
|
|
111
|
+
|
|
112
|
+
**Prompt 1 — Reproduction steps:**
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"questions": [{
|
|
116
|
+
"question": "What did you do to trigger the issue? Describe the exact steps to reproduce.",
|
|
117
|
+
"header": "Bug Intake (1/3) — Reproduction Steps"
|
|
118
|
+
}]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
Store the answer as `steps`. If blank, re-prompt before continuing.
|
|
122
|
+
|
|
123
|
+
**Prompt 2 — Expected behaviour:**
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"questions": [{
|
|
127
|
+
"question": "What did you expect to happen?",
|
|
128
|
+
"header": "Bug Intake (2/3) — Expected Behaviour"
|
|
129
|
+
}]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
Store as `expected`. If blank, re-prompt.
|
|
133
|
+
|
|
134
|
+
**Prompt 3 — Actual behaviour:**
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"questions": [{
|
|
138
|
+
"question": "What actually happened? Include any error messages, wrong output, or missing behaviour.",
|
|
139
|
+
"header": "Bug Intake (3/3) — Actual Behaviour"
|
|
140
|
+
}]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
Store as `actual`. If blank, re-prompt.
|
|
144
|
+
|
|
145
|
+
**Echo and confirm:**
|
|
146
|
+
|
|
147
|
+
Print the structured bug report:
|
|
148
|
+
```
|
|
149
|
+
## Bug Report
|
|
150
|
+
|
|
151
|
+
- **Steps**: {steps}
|
|
152
|
+
- **Expected**: {expected}
|
|
153
|
+
- **Actual**: {actual}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Then ask for confirmation:
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"questions": [{
|
|
160
|
+
"question": "Does this bug report look correct?",
|
|
161
|
+
"header": "Confirm Bug Report",
|
|
162
|
+
"options": [
|
|
163
|
+
{"label": "Looks good — start investigating", "description": "Proceed to root cause analysis"},
|
|
164
|
+
{"label": "Edit report", "description": "Re-enter all three fields"}
|
|
165
|
+
],
|
|
166
|
+
"multiSelect": false
|
|
167
|
+
}]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
- **Edit report**: re-run all three prompts from the beginning.
|
|
171
|
+
- **Looks good**: proceed to Step 4.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Step 4 — Investigation and Fix
|
|
176
|
+
|
|
177
|
+
Diagnose the root cause and apply a targeted fix following existing codebase conventions.
|
|
178
|
+
|
|
179
|
+
1. **Read the PR diff**:
|
|
180
|
+
```bash
|
|
181
|
+
gh pr diff {prNumber}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
2. **Read relevant source files** using Read, Grep, and Glob based on the bug report and diff context. Focus on files implicated by the reproduction steps and the PR changes.
|
|
185
|
+
|
|
186
|
+
3. **State root cause** — before making any file edits, output:
|
|
187
|
+
```
|
|
188
|
+
Root cause: {explanation in plain English}
|
|
189
|
+
```
|
|
190
|
+
This is required. Do not skip to editing without this statement.
|
|
191
|
+
|
|
192
|
+
4. **Scope check** — if fixing the bug requires editing files that are not directly related to the reported issue:
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"questions": [{
|
|
196
|
+
"question": "Fixing this bug requires editing files outside the immediate scope of the bug report:\n\n{list of additional files}\n\nProceed?",
|
|
197
|
+
"header": "Expanded Fix Scope",
|
|
198
|
+
"options": [
|
|
199
|
+
{"label": "Continue", "description": "Proceed with the expanded scope"},
|
|
200
|
+
{"label": "Abort", "description": "Stop here without editing any files"}
|
|
201
|
+
],
|
|
202
|
+
"multiSelect": false
|
|
203
|
+
}]
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
5. **Apply the fix** — edit only what is necessary to resolve the reported issue. No refactoring beyond the fix, no new features.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Step 5 — Full Build Validation, Commit, and Push
|
|
212
|
+
|
|
213
|
+
Detect the tech stack for each affected directory, run its full build locally, then commit and push.
|
|
214
|
+
|
|
215
|
+
### Stack Detection
|
|
216
|
+
|
|
217
|
+
1. Get changed files: `git diff --name-only` (unstaged) and `git diff --name-only --cached` (staged) — union of both.
|
|
218
|
+
|
|
219
|
+
2. Extract the unique top-level directory from each path (e.g. `conductor-backend/src/...` → `conductor-backend`). Only consider directories that contain at least one changed file.
|
|
220
|
+
|
|
221
|
+
3. For each affected directory, detect stack in this order (first match wins):
|
|
222
|
+
- Glob `{dir}/pom.xml` exists → **Maven/Spring Boot** → build command: `cd {dir} && mvn clean install`
|
|
223
|
+
- Glob `{dir}/next.config.ts` or `{dir}/next.config.js` exists → **Next.js** → build command: `cd {dir} && npm run build && npm run lint && npm run test`
|
|
224
|
+
- Glob `{dir}/package.json` exists → **Node.js** → build command: `cd {dir} && npm run build && npm test`
|
|
225
|
+
|
|
226
|
+
4. Run the build command for each affected directory.
|
|
227
|
+
- If a build command exits non-zero:
|
|
228
|
+
- Diagnose the build error from its output
|
|
229
|
+
- Apply a targeted fix to resolve the build failure
|
|
230
|
+
- Re-run the same build command
|
|
231
|
+
- **Never commit while any build command returns non-zero.** If the build cannot be fixed, halt and report the error to the user.
|
|
232
|
+
|
|
233
|
+
### Commit
|
|
234
|
+
|
|
235
|
+
Once all builds exit 0, commit with this format:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
fix({displayId}): {brief description of what was fixed}
|
|
239
|
+
|
|
240
|
+
What was broken: {description from bug report}
|
|
241
|
+
Root cause: {root cause identified in Step 4}
|
|
242
|
+
What changed: {what files were modified and why}
|
|
243
|
+
|
|
244
|
+
Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Use a HEREDOC to pass the message:
|
|
248
|
+
```bash
|
|
249
|
+
git add {changed files}
|
|
250
|
+
git commit -m "$(cat <<'EOF'
|
|
251
|
+
fix({displayId}): {brief description}
|
|
252
|
+
|
|
253
|
+
What was broken: {steps/actual from bug report}
|
|
254
|
+
Root cause: {root cause}
|
|
255
|
+
What changed: {summary of edits}
|
|
256
|
+
|
|
257
|
+
Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
|
|
258
|
+
EOF
|
|
259
|
+
)"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Push
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
git push origin {branch}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Show the PR URL to the user after a successful push.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Step 6 — Issue Status Round-Trip
|
|
273
|
+
|
|
274
|
+
After the push succeeds, transition the issue back to `CODE_REVIEW`:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
set_issue_status(issueId, "CODE_REVIEW")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Check the response for a `warning` field:
|
|
281
|
+
- If present:
|
|
282
|
+
> ⚠️ Status update to CODE_REVIEW failed (queued): {warning}
|
|
283
|
+
> Run `conductor start` to drain the sync queue, or update the status manually in the UI.
|
|
284
|
+
- Otherwise print: `✓ Issue {displayId} moved back to CODE_REVIEW`
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Step 7 — CI Monitoring (Two-Check Maximum)
|
|
289
|
+
|
|
290
|
+
**Check 1** — run immediately after push:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
gh pr checks {prUrl}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- **All green**: report each check name and status, then proceed to Final Summary.
|
|
297
|
+
- **Any pending or running**: proceed to Check 2.
|
|
298
|
+
|
|
299
|
+
**Check 2** — schedule exactly one wakeup:
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
ScheduleWakeup(delaySeconds=240, reason="Final CI check for {prUrl}", prompt="/conductor:fix")
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
On wake, run `gh pr checks {prUrl}` one final time.
|
|
306
|
+
|
|
307
|
+
Report each check: name, status (pass/fail/pending).
|
|
308
|
+
|
|
309
|
+
If checks are **still pending** on this second call:
|
|
310
|
+
> CI still running — check manually: {prUrl}
|
|
311
|
+
|
|
312
|
+
**Never schedule a third check.** Stop after the second check regardless of result.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Final Summary
|
|
317
|
+
|
|
318
|
+
After the last CI check (or immediately after push if all green), print:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
## Fix Complete
|
|
322
|
+
|
|
323
|
+
Issue: {displayId} — {issue_title}
|
|
324
|
+
Branch: {branch}
|
|
325
|
+
PR: {prUrl}
|
|
326
|
+
|
|
327
|
+
CI: {all green | still running — check manually: {prUrl}}
|
|
328
|
+
```
|
package/package.json
CHANGED