chief-clancy 0.5.4 → 0.5.6

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 (71) hide show
  1. package/README.md +3 -3
  2. package/dist/bundle/clancy-once.js +54 -29
  3. package/dist/installer/install.js +1 -1
  4. package/dist/installer/install.js.map +1 -1
  5. package/dist/schemas/bitbucket-pr.d.ts +122 -0
  6. package/dist/schemas/bitbucket-pr.d.ts.map +1 -0
  7. package/dist/schemas/bitbucket-pr.js +69 -0
  8. package/dist/schemas/bitbucket-pr.js.map +1 -0
  9. package/dist/schemas/env.d.ts +12 -0
  10. package/dist/schemas/env.d.ts.map +1 -1
  11. package/dist/schemas/env.js +4 -0
  12. package/dist/schemas/env.js.map +1 -1
  13. package/dist/schemas/github.d.ts +60 -0
  14. package/dist/schemas/github.d.ts.map +1 -1
  15. package/dist/schemas/github.js +32 -0
  16. package/dist/schemas/github.js.map +1 -1
  17. package/dist/schemas/gitlab-mr.d.ts +62 -0
  18. package/dist/schemas/gitlab-mr.d.ts.map +1 -0
  19. package/dist/schemas/gitlab-mr.js +31 -0
  20. package/dist/schemas/gitlab-mr.js.map +1 -0
  21. package/dist/scripts/once/once.d.ts.map +1 -1
  22. package/dist/scripts/once/once.js +181 -23
  23. package/dist/scripts/once/once.js.map +1 -1
  24. package/dist/scripts/shared/git-ops/git-ops.d.ts +9 -0
  25. package/dist/scripts/shared/git-ops/git-ops.d.ts.map +1 -1
  26. package/dist/scripts/shared/git-ops/git-ops.js +20 -0
  27. package/dist/scripts/shared/git-ops/git-ops.js.map +1 -1
  28. package/dist/scripts/shared/progress/progress.d.ts +41 -0
  29. package/dist/scripts/shared/progress/progress.d.ts.map +1 -1
  30. package/dist/scripts/shared/progress/progress.js +96 -1
  31. package/dist/scripts/shared/progress/progress.js.map +1 -1
  32. package/dist/scripts/shared/prompt/prompt.d.ts +27 -0
  33. package/dist/scripts/shared/prompt/prompt.d.ts.map +1 -1
  34. package/dist/scripts/shared/prompt/prompt.js +32 -7
  35. package/dist/scripts/shared/prompt/prompt.js.map +1 -1
  36. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts +41 -9
  37. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts.map +1 -1
  38. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js +182 -0
  39. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js.map +1 -1
  40. package/dist/scripts/shared/pull-request/github/github.d.ts +34 -1
  41. package/dist/scripts/shared/pull-request/github/github.d.ts.map +1 -1
  42. package/dist/scripts/shared/pull-request/github/github.js +106 -2
  43. package/dist/scripts/shared/pull-request/github/github.js.map +1 -1
  44. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts +32 -9
  45. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts.map +1 -1
  46. package/dist/scripts/shared/pull-request/gitlab/gitlab.js +127 -0
  47. package/dist/scripts/shared/pull-request/gitlab/gitlab.js.map +1 -1
  48. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts.map +1 -1
  49. package/dist/scripts/shared/pull-request/pr-body/pr-body.js +7 -0
  50. package/dist/scripts/shared/pull-request/pr-body/pr-body.js.map +1 -1
  51. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts +23 -0
  52. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts.map +1 -0
  53. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js +30 -0
  54. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js.map +1 -0
  55. package/dist/types/index.d.ts +1 -1
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/dist/types/remote.d.ts +9 -0
  58. package/dist/types/remote.d.ts.map +1 -1
  59. package/package.json +1 -1
  60. package/src/roles/planner/commands/approve-plan.md +7 -0
  61. package/src/roles/planner/commands/plan.md +11 -1
  62. package/src/roles/planner/workflows/approve-plan.md +478 -0
  63. package/src/roles/planner/workflows/plan.md +171 -49
  64. package/src/roles/reviewer/workflows/logs.md +7 -3
  65. package/src/roles/setup/commands/help.md +3 -2
  66. package/src/roles/setup/workflows/init.md +68 -2
  67. package/src/roles/setup/workflows/scaffold.md +41 -0
  68. package/src/roles/setup/workflows/settings.md +41 -6
  69. package/src/templates/CLAUDE.md +2 -0
  70. package/src/roles/planner/commands/approve.md +0 -7
  71. package/src/roles/planner/workflows/approve.md +0 -237
@@ -16,7 +16,13 @@ Fetch backlog tickets from the board, explore the codebase, and generate structu
16
16
 
17
17
  2. Source `.clancy/.env` and check board credentials are present.
18
18
 
19
- 3. Check `.clancy/docs/` if the directory is empty or missing:
19
+ 3. Check `CLANCY_ROLES` includes `planner` (or env var is unset, which indicates a global install where all roles are available). If `CLANCY_ROLES` is set but does not include `planner`:
20
+ ```
21
+ The Planner role is not enabled. Add "planner" to CLANCY_ROLES in .clancy/.env or run /clancy:settings.
22
+ ```
23
+ Stop.
24
+
25
+ 4. Check `.clancy/docs/` — if the directory is empty or missing:
20
26
  ```
21
27
  ⚠️ No codebase documentation found in .clancy/docs/
22
28
  Plans will be less accurate without codebase context.
@@ -26,16 +32,37 @@ Fetch backlog tickets from the board, explore the codebase, and generate structu
26
32
  ```
27
33
  If the user declines, stop. If they confirm, continue without docs context.
28
34
 
35
+ 5. Branch freshness check — run `git fetch origin` and compare the current HEAD with `origin/$CLANCY_BASE_BRANCH` (defaults to `main`). If the local branch is behind:
36
+ ```
37
+ ⚠️ Your local branch is behind origin/{CLANCY_BASE_BRANCH} by {N} commit(s).
38
+
39
+ [1] Pull latest
40
+ [2] Continue anyway
41
+ [3] Abort
42
+ ```
43
+ - [1] runs `git pull origin $CLANCY_BASE_BRANCH` and continues
44
+ - [2] continues without pulling
45
+ - [3] stops
46
+
29
47
  ---
30
48
 
31
49
  ## Step 2 — Parse arguments
32
50
 
33
51
  Parse the arguments passed to the command:
34
52
 
35
- - **No argument:** plan 1 ticket
36
- - **Numeric argument** (e.g. `/clancy:plan 3`): plan up to N tickets, cap at 10
37
- - **`--force`:** re-plan tickets that already have a plan (reads feedback comments)
38
- - Arguments can appear in any order (e.g. `/clancy:plan 3 --force` or `/clancy:plan --force 3`)
53
+ - **No argument:** plan 1 ticket from the queue
54
+ - **Numeric argument** (e.g. `/clancy:plan 3`): plan up to N tickets from the queue, cap at 10
55
+ - **Specific ticket key:** plan a single ticket by key, with per-platform validation:
56
+ - `#42` valid for GitHub only. If board is Jira or Linear: `The #N format is for GitHub Issues. Use a ticket key like PROJ-123.` Stop.
57
+ - `PROJ-123` / `ENG-42` (letters-dash-number) — valid for Jira and Linear. If board is GitHub: `Use #N format for GitHub Issues (e.g. #42).` Stop.
58
+ - Bare integer on GitHub (e.g. `/clancy:plan 42` where 42 > 10): ambiguous — ask:
59
+ ```
60
+ Did you mean issue #42 or batch mode (42 tickets)?
61
+ [1] Plan issue #42
62
+ [2] Plan 10 tickets (max batch)
63
+ ```
64
+ - **`--fresh`:** discard any existing plan and start over from scratch. This is NOT re-plan with feedback — it ignores existing plans entirely.
65
+ - Arguments can appear in any order (e.g. `/clancy:plan --fresh PROJ-123` or `/clancy:plan PROJ-123 --fresh`)
39
66
 
40
67
  If N > 10: `Maximum batch size is 10. Planning 10 tickets.`
41
68
 
@@ -50,7 +77,61 @@ Planning {N} tickets — each requires codebase exploration. Continue? [Y/n]
50
77
 
51
78
  Detect board from `.clancy/.env` and fetch tickets from the **planning queue** (different from the implementation queue used by `/clancy:once`).
52
79
 
53
- ### Jira
80
+ ### Specific ticket key (if provided)
81
+
82
+ If a specific ticket key was parsed in Step 2, fetch that single ticket instead of the queue:
83
+
84
+ #### GitHub — Fetch specific issue
85
+
86
+ ```bash
87
+ RESPONSE=$(curl -s \
88
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
89
+ -H "X-GitHub-Api-Version: 2022-11-28" \
90
+ "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER")
91
+ ```
92
+
93
+ Validate the response:
94
+ - If `pull_request` field is present (not null): `#{N} is a PR, not an issue.` Stop.
95
+ - If `state` is `closed`: warn `Issue #${N} is closed. Plan anyway? [y/N]`
96
+
97
+ #### Jira — Fetch specific ticket
98
+
99
+ ```bash
100
+ RESPONSE=$(curl -s \
101
+ -u "$JIRA_USER:$JIRA_API_TOKEN" \
102
+ -H "Accept: application/json" \
103
+ "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY?fields=summary,description,issuelinks,parent,customfield_10014,comment,status,issuetype")
104
+ ```
105
+
106
+ Validate the response:
107
+ - If `fields.status.statusCategory.key` is `done`: warn `Ticket is done. Plan anyway? [y/N]`
108
+ - If `fields.issuetype.name` is `Epic`: note `This is an epic.` (continue normally)
109
+
110
+ #### Linear — Fetch specific issue
111
+
112
+ ```graphql
113
+ query {
114
+ issues(filter: { identifier: { eq: "$IDENTIFIER" } }) {
115
+ nodes {
116
+ id identifier title description
117
+ state { type name }
118
+ parent { identifier title }
119
+ comments { nodes { id body createdAt user { id } } }
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ Validate the response:
126
+ - If `nodes` is empty: `Issue {KEY} not found on Linear.` Stop.
127
+ - If `state.type` is `completed`: warn `Issue is completed. Plan anyway? [y/N]`
128
+ - If `state.type` is `canceled`: warn `Issue is canceled. Plan anyway? [y/N]`
129
+
130
+ Then skip to Step 3b with this single ticket.
131
+
132
+ ### Queue fetch (no specific key)
133
+
134
+ #### Jira
54
135
 
55
136
  Build the JQL using planning-specific env vars:
56
137
  - `CLANCY_PLAN_STATUS` defaults to `Backlog` if not set
@@ -71,7 +152,7 @@ RESPONSE=$(curl -s \
71
152
 
72
153
  Note: include the `comment` field so we can check for existing plans and read feedback.
73
154
 
74
- ### GitHub Issues
155
+ #### GitHub Issues
75
156
 
76
157
  First resolve the authenticated username (don't use `@me` — it breaks with fine-grained PATs):
77
158
  ```bash
@@ -90,7 +171,7 @@ RESPONSE=$(curl -s \
90
171
  - Filter out PRs (entries with `pull_request` key)
91
172
  - For each issue, fetch comments: `GET /repos/$GITHUB_REPO/issues/{number}/comments`
92
173
 
93
- ### Linear
174
+ #### Linear
94
175
 
95
176
  Build the filter using `CLANCY_PLAN_STATE_TYPE` (defaults to `backlog` if not set):
96
177
 
@@ -108,7 +189,7 @@ query {
108
189
  nodes {
109
190
  id identifier title description
110
191
  parent { identifier title }
111
- comments { nodes { body createdAt } }
192
+ comments { nodes { id body createdAt user { id } } }
112
193
  }
113
194
  }
114
195
  }
@@ -129,27 +210,46 @@ If no tickets found:
129
210
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
130
211
 
131
212
  "Nothing to see here." — No backlog tickets to plan.
132
-
133
- Check your board configuration or run /clancy:settings to verify the plan queue.
134
- {If GitHub: "For GitHub: planning uses the \"$CLANCY_PLAN_LABEL\" label (default: needs-refinement), not \"clancy\". Apply that label to issues you want planned."}
135
213
  ```
214
+
215
+ Then display board-specific guidance:
216
+
217
+ - **GitHub:** `For GitHub: planning uses the "$CLANCY_PLAN_LABEL" label (default: needs-refinement), not "clancy". Apply that label to issues you want planned.`
218
+ - **Jira:** `Check that CLANCY_PLAN_STATUS (currently: "$CLANCY_PLAN_STATUS") matches a status in your Jira project, and that tickets in that status are assigned to you.`
219
+ - **Linear:** `Check that CLANCY_PLAN_STATE_TYPE (currently: "$CLANCY_PLAN_STATE_TYPE") is a valid Linear state type (backlog, unstarted, started, completed, canceled, triage), and that tickets in that state are assigned to you in team $LINEAR_TEAM_ID.`
220
+
136
221
  Stop.
137
222
 
138
223
  ---
139
224
 
140
- ## Step 3b — Check for existing plans (unless --force)
225
+ ## Step 3b — Check for existing plans
226
+
227
+ For each ticket, scan its comments for the marker `## Clancy Implementation Plan`. Then apply the following logic:
141
228
 
142
- For each ticket, scan its comments for the marker `## Clancy Implementation Plan`:
229
+ | Condition | Behaviour |
230
+ |---|---|
231
+ | Has plan + feedback comments found after the plan | Revise: proceed to Step 3c to read feedback, then generate a revised plan |
232
+ | Has plan + `--fresh` flag | Discard existing plan, proceed to Step 4 (fresh plan from scratch) |
233
+ | Has plan + no feedback + no `--fresh` | Stop for this ticket: `Already planned. Comment on the ticket to provide feedback, then re-run /clancy:plan {KEY} to revise. Or use --fresh to start over.` |
234
+ | No plan found | Proceed to Step 4 |
143
235
 
144
- - **No plan found:** proceed to step 4
145
- - **Has plan, no `--force`:** skip display `⏭️ [{KEY}] already planned. Use --force to re-plan.`
146
- - **Has plan, with `--force`:** proceed to step 3c
236
+ Feedback detection per platform:
237
+ - **GitHub:** comments posted after the plan comment where `user.login != $GITHUB_USERNAME` (the resolved username)
238
+ - **Jira:** comments posted after the plan comment where `author.accountId != plan_comment.author.accountId`
239
+ - **Linear:** all comments posted after the plan comment are treated as feedback (Linear personal keys don't expose viewer ID easily in comment context)
147
240
 
148
241
  ---
149
242
 
150
- ## Step 3c — Read feedback comments (--force only)
243
+ ## Step 3c — Read feedback comments
244
+
245
+ When revising a plan (auto-detected from feedback comments after the existing plan), read all comments posted AFTER the most recent `## Clancy Implementation Plan` comment.
246
+
247
+ Filter out the planner's own comments:
248
+ - **GitHub:** exclude comments where `user.login == $GITHUB_USERNAME` (the resolved username)
249
+ - **Jira:** exclude comments by the same `author.accountId` as the plan comment
250
+ - **Linear:** all post-plan comments are treated as feedback
151
251
 
152
- When re-planning, read all comments posted AFTER the most recent `## Clancy Implementation Plan` comment. These are presumed to be PO/team feedback. No special syntax needed — they just comment normally on the ticket.
252
+ These are presumed to be PO/team feedback. No special syntax needed — they just comment normally on the ticket.
153
253
 
154
254
  Pass this feedback to the plan generation step as additional context.
155
255
 
@@ -188,12 +288,27 @@ Before spending time exploring files, scan the ticket title and description for
188
288
  - Non-code deliverables: "write a runbook", "create a presentation", "update the wiki"
189
289
  - Infrastructure ops: "rotate API keys in prod", "scale the fleet", "restart the service"
190
290
 
291
+ **STACK.md cross-reference:** If `.clancy/docs/STACK.md` exists, read it. If the ticket mentions a technology not listed in STACK.md, flag it as a concern (but do not skip — include a note in the plan's Risks section instead).
292
+
191
293
  If infeasible:
192
294
  ```
193
295
  ⏭️ [{KEY}] {Title} — not a codebase change. Skipping.
194
296
  → {reason, e.g. "Ticket describes work in Google Tag Manager, not in the codebase."}
195
297
  ```
196
298
 
299
+ **Post skip comment to board:** Check `CLANCY_SKIP_COMMENTS` env var (default: `true`). If not `false`, post a brief comment on the ticket:
300
+
301
+ > Clancy skipped this ticket: {reason}
302
+ >
303
+ > This ticket appears to require work outside the codebase (e.g. {specific signal}). If this is incorrect, add more context to the ticket description and re-run `/clancy:plan`.
304
+
305
+ Use the same comment API patterns as Step 5 (plan posting). Best-effort — warn on failure, do not stop.
306
+
307
+ **Log SKIPPED entry:** Append to `.clancy/progress.txt`:
308
+ ```
309
+ YYYY-MM-DD HH:MM | {KEY} | SKIPPED | {reason}
310
+ ```
311
+
197
312
  Continue to the next ticket. **Pass signals:** Anything mentioning code, components, features, bugs, UI, API, tests, refactoring, or lacking enough context to determine (benefit of the doubt).
198
313
 
199
314
  ### 4b. Check for previous implementation (QA return detection)
@@ -246,38 +361,40 @@ Write the plan in this exact template:
246
361
  ### Summary
247
362
  {1-3 sentences: what this ticket asks for, why it matters, gaps filled}
248
363
 
249
- ### Acceptance Criteria
250
- - [ ] {Specific, testable criterion}
251
- - [ ] {Specific, testable criterion}
252
- - [ ] {Specific, testable criterion}
253
-
254
- ### Technical Approach
255
- {2-4 sentences: implementation strategy, patterns, key decisions}
256
-
257
364
  ### Affected Files
258
- | File | Change |
259
- |------|--------|
260
- | `src/path/file.ts` | {What changes and why} |
261
- | `src/path/file.test.ts` | {What changes and why} |
365
+ | File | Change Type | Description |
366
+ |------|-------------|-------------|
367
+ | `src/path/file.ts` | Modify | {What changes and why} |
368
+ | `src/path/new-file.ts` | Create | {What this new file does} |
369
+ | `src/path/file.test.ts` | Modify | {What changes and why} |
262
370
 
263
- ### Edge Cases
264
- - {Specific edge case and handling}
265
- - {Specific edge case and handling}
371
+ ### Implementation Approach
372
+ {2-4 sentences: implementation strategy, patterns, key decisions}
266
373
 
267
- ### Test Plan
374
+ ### Test Strategy
268
375
  - [ ] {Specific test to write or verify}
269
376
  - [ ] {Specific test to write or verify}
270
377
 
378
+ ### Acceptance Criteria
379
+ - [ ] {Specific, testable criterion}
380
+ - [ ] {Specific, testable criterion}
381
+ - [ ] {Specific, testable criterion}
382
+
271
383
  ### Dependencies
272
384
  {Blockers, prerequisites, external deps. "None" if clean.}
273
385
 
386
+ ### Figma Link
387
+ {If a Figma URL was found in the ticket, include it here. Otherwise omit this section entirely.}
388
+
389
+ ### Risks / Considerations
390
+ - {Specific risk or consideration and handling}
391
+ - {Specific risk or consideration and handling}
392
+
274
393
  ### Size Estimate
275
394
  **{S / M / L}** — {Brief justification}
276
395
 
277
396
  ---
278
- *Generated by [Clancy](https://github.com/Pushedskydiver/clancy).
279
- To request changes: comment on this ticket, then run `/clancy:plan --force` to re-plan with your feedback.
280
- To approve: run `/clancy:approve {KEY}` to promote this plan to the ticket description.*
397
+ *Generated by [Clancy](https://github.com/Pushedskydiver/clancy). To request changes: comment on this ticket, then re-run `/clancy:plan` to revise. To start over: `/clancy:plan --fresh`. To approve: `/clancy:approve-plan {KEY}`.*
281
398
  ```
282
399
 
283
400
  **If re-planning with feedback**, prepend a section before Summary:
@@ -289,11 +406,11 @@ To approve: run `/clancy:approve {KEY}` to promote this plan to the ticket descr
289
406
  **Quality rules:**
290
407
  - Acceptance criteria must be testable ("user can X", "system does Y"), never vague
291
408
  - Affected files must be real files found during exploration, not guesses
292
- - Edge cases must be specific to this ticket, not generic
409
+ - Risks / Considerations must be specific to this ticket, not generic
293
410
  - Size: S (< 1 hour, few files), M (1-4 hours, moderate), L (4+ hours, significant)
294
411
  - If affected files > 15: add a note "Consider splitting this ticket"
295
412
  - If UI ticket without Figma URL: note in plan
296
- - If ticket mentions tech not in STACK.md: note in plan
413
+ - If ticket mentions tech not in STACK.md: note in Risks / Considerations
297
414
 
298
415
  **Dependency detection:**
299
416
 
@@ -368,10 +485,14 @@ Linear accepts Markdown directly.
368
485
 
369
486
  ## Step 6 — Log
370
487
 
371
- For each planned ticket, append to `.clancy/progress.txt`:
372
- ```
373
- YYYY-MM-DD HH:MM | {KEY} | PLAN | {S/M/L}
374
- ```
488
+ For each planned ticket, append to `.clancy/progress.txt` using the appropriate variant:
489
+
490
+ | Outcome | Log entry |
491
+ |---|---|
492
+ | Normal | `YYYY-MM-DD HH:MM \| {KEY} \| PLAN \| {S/M/L}` |
493
+ | Revised (re-plan with feedback) | `YYYY-MM-DD HH:MM \| {KEY} \| REVISED \| {S/M/L}` |
494
+ | Comment post failed | `YYYY-MM-DD HH:MM \| {KEY} \| POST_FAILED \| {reason}` |
495
+ | Skipped (infeasible) | `YYYY-MM-DD HH:MM \| {KEY} \| SKIPPED \| {reason}` |
375
496
 
376
497
  ---
377
498
 
@@ -385,9 +506,9 @@ Planned {N} ticket(s):
385
506
  ✅ [{KEY1}] {Title} — M | 6 files | Comment posted
386
507
  ✅ [{KEY2}] {Title} — S | 2 files | Comment posted
387
508
  ⏭️ [{KEY3}] {Title} — already planned
388
- ⏭️ [{KEY4}] {Title} — infeasible (external admin)
509
+ ⏭️ [{KEY4}] {Title} — not a codebase change
389
510
 
390
- Plans written to your board. After review, run /clancy:approve {KEY} to promote.
511
+ Plans written to your board. After review, run /clancy:approve-plan {KEY} to promote.
391
512
 
392
513
  "Let me dust this for prints..."
393
514
  ```
@@ -397,9 +518,10 @@ Plans written to your board. After review, run /clancy:approve {KEY} to promote.
397
518
  ## Notes
398
519
 
399
520
  - This command does NOT implement anything — it generates plans only
400
- - Plans are posted as comments, never overwriting the ticket description (that's `/clancy:approve`)
401
- - Re-running without `--force` safely skips already-planned tickets
521
+ - Plans are posted as comments, never overwriting the ticket description (that's `/clancy:approve-plan`)
522
+ - Re-running without `--fresh` auto-detects feedback: if feedback exists, revises; if no feedback, stops with guidance
523
+ - The `--fresh` flag discards the existing plan entirely and generates a new one from scratch
402
524
  - The planning queue is separate from the implementation queue — they never compete for the same tickets
403
525
  - All board API calls are best-effort — if a comment fails to post, print the plan to stdout as fallback
404
526
  - When exploring the codebase, use Glob and Read for small tickets, parallel Explore subagents for larger ones
405
- - The `## Clancy Implementation Plan` marker in comments is used by both `/clancy:plan` (to detect existing plans) and `/clancy:approve` (to find the plan to promote)
527
+ - The `## Clancy Implementation Plan` marker in comments is used by both `/clancy:plan` (to detect existing plans) and `/clancy:approve-plan` (to find the plan to promote)
@@ -27,21 +27,23 @@ Each line has one of these formats:
27
27
  - `YYYY-MM-DD HH:MM | TICKET-KEY | Summary | DONE` — completed implementation
28
28
  - `YYYY-MM-DD HH:MM | TICKET-KEY | REVIEW | {score}%` — ticket review
29
29
  - `YYYY-MM-DD HH:MM | TICKET-KEY | PLAN | {S/M/L}` — plan generated
30
+ - `YYYY-MM-DD HH:MM | TICKET-KEY | REVISED | {S/M/L}` — plan revised after feedback
30
31
  - `YYYY-MM-DD HH:MM | TICKET-KEY | APPROVE | —` — plan promoted to description
31
32
  - `YYYY-MM-DD HH:MM | TICKET-KEY | SKIPPED | {reason}` — ticket skipped
33
+ - `YYYY-MM-DD HH:MM | TICKET-KEY | POST_FAILED | {reason}` — failed to post comment to board
32
34
 
33
35
  Parse each line:
34
36
  - Date (YYYY-MM-DD)
35
37
  - Time (HH:MM)
36
38
  - Ticket key (e.g. PROJ-42)
37
- - Action type (DONE, REVIEW, PLAN, APPROVE, SKIPPED, or summary text)
39
+ - Action type (DONE, REVIEW, PLAN, REVISED, APPROVE, SKIPPED, POST_FAILED, or summary text)
38
40
  - Detail (status, score, size, or reason)
39
41
 
40
42
  Extract:
41
43
  - Total DONE tickets
42
44
  - First and latest run dates
43
45
  - All DONE tickets from the current calendar week (Mon–Sun)
44
- - Counts for each action type: PLAN, APPROVE, REVIEW, SKIPPED
46
+ - Counts for each action type: PLAN, REVISED, APPROVE, REVIEW, SKIPPED, POST_FAILED
45
47
  - Epic key from ticket key — e.g. PROJ-42 → epic likely PROJ-10 (use parent field if logged, otherwise group by project prefix)
46
48
 
47
49
  ---
@@ -71,9 +73,11 @@ By epic:
71
73
  (other) {bar} {count} tickets
72
74
 
73
75
  Plans generated: {N} (only show if > 0)
76
+ Plans revised: {N} (only show if > 0)
74
77
  Plans approved: {N} (only show if > 0)
75
78
  Reviews run: {N} (only show if > 0)
76
79
  Tickets skipped: {N} (only show if > 0)
80
+ Post failures: {N} (only show if > 0)
77
81
  Full log: .clancy/progress.txt
78
82
 
79
83
  "The law is powerless to help you, but here's what Clancy's done."
@@ -86,7 +90,7 @@ Full log: .clancy/progress.txt
86
90
  - Progress bars: ASCII, proportional to highest count, width 10 chars, `█` filled, `░` empty
87
91
  - Epic grouping: group by epic key in the ticket's parent field (from progress.txt if logged), or by project prefix if not available
88
92
  - Tickets without an epic: group under `(other)`
89
- - REVIEW, PLAN, APPROVE, and SKIPPED lines: shown separately at the end as counts — not included in ticket count
93
+ - REVIEW, PLAN, REVISED, APPROVE, SKIPPED, and POST_FAILED lines: shown separately at the end as counts — not included in ticket count
90
94
 
91
95
  ---
92
96
 
@@ -18,8 +18,9 @@ integration, structured codebase docs, and a git workflow built for team develop
18
18
  |---|---|
19
19
  | `/clancy:plan` | Refine backlog tickets into structured implementation plans |
20
20
  | `/clancy:plan 3` | Plan up to 3 tickets in batch mode |
21
- | `/clancy:plan --force` | Re-plan tickets that already have a plan (reads feedback) |
22
- | `/clancy:approve` | Promote an approved plan to the ticket description |
21
+ | `/clancy:plan PROJ-123` | Plan a specific ticket by key (also `#42`, `ENG-42`) |
22
+ | `/clancy:plan --fresh` | Discard any existing plan and start from scratch |
23
+ | `/clancy:approve-plan` | Promote an approved plan to the ticket description |
23
24
 
24
25
  ### Implementer
25
26
 
@@ -406,6 +406,21 @@ Same storage logic as Jira above.
406
406
 
407
407
  ---
408
408
 
409
+ ### Q3e (all boards): Max rework cycles
410
+
411
+ PR-based rework detection is automatic — no configuration needed. This setting controls the safety limit.
412
+
413
+ Output:
414
+
415
+ ```
416
+ Max rework cycles before flagging for human intervention? [3]
417
+ ```
418
+
419
+ If a number is entered: store as `CLANCY_MAX_REWORK` in `.clancy/.env`.
420
+ If enter is pressed with no value: use default 3 — store `CLANCY_MAX_REWORK=3` in `.clancy/.env`.
421
+
422
+ ---
423
+
409
424
  ### Q4: Base branch (auto-detect)
410
425
 
411
426
  Silently detect the base branch — do not ask unless detection fails:
@@ -489,13 +504,13 @@ Note: as more roles are added in future versions, they appear as additional numb
489
504
 
490
505
  ---
491
506
 
492
- ## Step 4d (Jira only, if Planner role selected): Planning queue status
507
+ ## Step 4d (if Planner role selected): Planning queue config
493
508
 
494
509
  Only ask this if the user selected Planner in Step 4c above (or if re-running init and `CLANCY_ROLES` already includes `planner`).
495
510
 
496
511
  If the planner role is not enabled, skip this step entirely.
497
512
 
498
- Output:
513
+ **Jira:** Output:
499
514
 
500
515
  ```
501
516
  The Planner role picks tickets from a separate queue for planning.
@@ -509,6 +524,57 @@ Which Jira status should Clancy pick planning tickets from?
509
524
  If [1]: store `CLANCY_PLAN_STATUS="Backlog"` in `.clancy/.env`.
510
525
  If [2]: prompt for the value, store as `CLANCY_PLAN_STATUS` in `.clancy/.env`. Wrap in double quotes.
511
526
 
527
+ **GitHub:** Output:
528
+
529
+ ```
530
+ The Planner role picks issues from a separate queue for planning.
531
+
532
+ Which GitHub label should Clancy pick planning issues from?
533
+
534
+ [1] needs-refinement (default)
535
+ [2] Enter a different label name
536
+ ```
537
+
538
+ If [1]: store `CLANCY_PLAN_LABEL="needs-refinement"` in `.clancy/.env`.
539
+ If [2]: prompt for the value, store as `CLANCY_PLAN_LABEL` in `.clancy/.env`. Wrap in double quotes.
540
+
541
+ **Linear:** Output:
542
+
543
+ ```
544
+ The Planner role picks issues from a separate queue for planning.
545
+
546
+ Which Linear state type should Clancy pick planning issues from?
547
+
548
+ [1] backlog (default)
549
+ [2] triage
550
+ [3] Enter a different value
551
+ ```
552
+
553
+ If [1]: store `CLANCY_PLAN_STATE_TYPE="backlog"` in `.clancy/.env`.
554
+ If [2]: store `CLANCY_PLAN_STATE_TYPE="triage"` in `.clancy/.env`.
555
+ If [3]: prompt for the value, store as `CLANCY_PLAN_STATE_TYPE` in `.clancy/.env`. Valid values: backlog, unstarted, started, completed, canceled, triage.
556
+
557
+ ---
558
+
559
+ ## Step 4e (Jira only, if Planner role selected): Post-approval transition
560
+
561
+ Only ask this if the user selected Planner in Step 4c above (or if re-running init and `CLANCY_ROLES` already includes `planner`), **and** the board is Jira.
562
+
563
+ If the planner role is not enabled, or the board is not Jira, skip this step entirely.
564
+
565
+ Output:
566
+
567
+ ```
568
+ After approving a plan, Clancy can transition the ticket to your implementation queue.
569
+ What status should Clancy transition to?
570
+
571
+ [1] Enter a status name (e.g. To Do, Ready)
572
+ [2] Skip — I'll move tickets manually
573
+ ```
574
+
575
+ If [1]: prompt for the value, store as `CLANCY_STATUS_PLANNED` in `.clancy/.env`. Wrap in double quotes.
576
+ If [2]: skip — no `CLANCY_STATUS_PLANNED` line written.
577
+
512
578
  ---
513
579
 
514
580
  ## Step 5 — Optional enhancements
@@ -396,11 +396,25 @@ MAX_ITERATIONS=5
396
396
  # CLANCY_GIT_PLATFORM=gitlab # override auto-detection (github/gitlab/bitbucket)
397
397
  # CLANCY_GIT_API_URL=https://gitlab.example.com/api/v4 # self-hosted git API base URL
398
398
 
399
+ # ─── Optional: Rework loop ──────────────────────────────────────────────────
400
+ # PR-based rework is automatic — when a reviewer leaves inline comments or
401
+ # a conversation comment prefixed with "Rework:", Clancy picks it up on the
402
+ # next run. No configuration needed.
403
+ # CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
404
+
399
405
  # ─── Optional: Planner queue ─────────────────────────────────────────────────
400
406
  # Status for backlog tickets that /clancy:plan fetches from (default: Backlog)
401
407
  # Only used if Planner role is enabled via CLANCY_ROLES
402
408
  # CLANCY_PLAN_STATUS="Backlog"
403
409
 
410
+ # After approving a plan, transition the ticket to this status (e.g. "To Do")
411
+ # CLANCY_STATUS_PLANNED="To Do"
412
+
413
+ # ─── Optional: Skip comments ──────────────────────────────────────────────
414
+ # When Clancy skips a ticket (irrelevant/infeasible), post a comment explaining why
415
+ # Set to "false" to disable skip comments
416
+ # CLANCY_SKIP_COMMENTS=true
417
+
404
418
  # ─── Optional: Notifications ──────────────────────────────────────────────────
405
419
  # Webhook URL for Slack or Teams notifications on ticket completion
406
420
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
@@ -457,6 +471,17 @@ MAX_ITERATIONS=20
457
471
  # PLAYWRIGHT_STORYBOOK_PORT=6006
458
472
  # PLAYWRIGHT_STARTUP_WAIT=15
459
473
 
474
+ # ─── Optional: Rework loop ──────────────────────────────────────────────────
475
+ # PR-based rework is automatic — when a reviewer leaves inline comments or
476
+ # a conversation comment prefixed with "Rework:", Clancy picks it up on the
477
+ # next run. No configuration needed.
478
+ # CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
479
+
480
+ # ─── Optional: Skip comments ──────────────────────────────────────────────
481
+ # When Clancy skips a ticket (irrelevant/infeasible), post a comment explaining why
482
+ # Set to "false" to disable skip comments
483
+ # CLANCY_SKIP_COMMENTS=true
484
+
460
485
  # ─── Optional: Notifications ──────────────────────────────────────────────────
461
486
  # Webhook URL for Slack or Teams notifications on ticket completion
462
487
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
@@ -478,6 +503,11 @@ LINEAR_TEAM_ID=your-team-uuid
478
503
  # Create the label in Linear first, then add it to any issue you want Clancy to pick up.
479
504
  # CLANCY_LABEL=clancy
480
505
 
506
+ # ─── Planner Queue (optional — requires CLANCY_ROLES to include "planner") ───
507
+ # State type for issues that /clancy:plan fetches from (default: backlog)
508
+ # Valid values: backlog, unstarted, started, completed, canceled, triage
509
+ # CLANCY_PLAN_STATE_TYPE="backlog"
510
+
481
511
  # ─── Git ──────────────────────────────────────────────────────────────────────
482
512
  # Base integration branch. Clancy branches from here when an issue has no parent.
483
513
  # When an issue has a parent, Clancy auto-creates epic/{key} from this branch.
@@ -513,6 +543,12 @@ MAX_ITERATIONS=20
513
543
  # CLANCY_STATUS_DONE="Done"
514
544
  # CLANCY_STATUS_REVIEW="In Review" # used when creating a PR instead of merging locally
515
545
 
546
+ # ─── Optional: Rework loop ──────────────────────────────────────────────────
547
+ # PR-based rework is automatic — when a reviewer leaves inline comments or
548
+ # a conversation comment prefixed with "Rework:", Clancy picks it up on the
549
+ # next run. No configuration needed.
550
+ # CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
551
+
516
552
  # ─── Optional: Git host (PR creation) ───────────────────────────────────────
517
553
  # When an issue has no parent, Clancy pushes the feature branch and creates a
518
554
  # pull request instead of squash-merging locally. Requires a git host token.
@@ -523,6 +559,11 @@ MAX_ITERATIONS=20
523
559
  # CLANCY_GIT_PLATFORM=gitlab # override auto-detection (github/gitlab/bitbucket)
524
560
  # CLANCY_GIT_API_URL=https://gitlab.example.com/api/v4 # self-hosted git API base URL
525
561
 
562
+ # ─── Optional: Skip comments ──────────────────────────────────────────────
563
+ # When Clancy skips a ticket (irrelevant/infeasible), post a comment explaining why
564
+ # Set to "false" to disable skip comments
565
+ # CLANCY_SKIP_COMMENTS=true
566
+
526
567
  # ─── Optional: Notifications ──────────────────────────────────────────────────
527
568
  # Webhook URL for Slack or Teams notifications on ticket completion
528
569
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url