chief-clancy 0.5.5 → 0.5.7

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 (68) hide show
  1. package/README.md +3 -3
  2. package/dist/bundle/clancy-once.js +38 -32
  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 +15 -0
  6. package/dist/schemas/bitbucket-pr.d.ts.map +1 -1
  7. package/dist/schemas/bitbucket-pr.js +6 -0
  8. package/dist/schemas/bitbucket-pr.js.map +1 -1
  9. package/dist/schemas/env.d.ts +8 -0
  10. package/dist/schemas/env.d.ts.map +1 -1
  11. package/dist/schemas/env.js +2 -0
  12. package/dist/schemas/env.js.map +1 -1
  13. package/dist/schemas/github.d.ts +12 -0
  14. package/dist/schemas/github.d.ts.map +1 -1
  15. package/dist/schemas/github.js +2 -0
  16. package/dist/schemas/github.js.map +1 -1
  17. package/dist/schemas/gitlab-mr.d.ts +11 -0
  18. package/dist/schemas/gitlab-mr.d.ts.map +1 -1
  19. package/dist/schemas/gitlab-mr.js +2 -0
  20. package/dist/schemas/gitlab-mr.js.map +1 -1
  21. package/dist/scripts/board/github/github.d.ts +1 -1
  22. package/dist/scripts/board/github/github.d.ts.map +1 -1
  23. package/dist/scripts/board/github/github.js +2 -2
  24. package/dist/scripts/board/github/github.js.map +1 -1
  25. package/dist/scripts/once/once.d.ts.map +1 -1
  26. package/dist/scripts/once/once.js +156 -25
  27. package/dist/scripts/once/once.js.map +1 -1
  28. package/dist/scripts/shared/git-ops/git-ops.d.ts +11 -0
  29. package/dist/scripts/shared/git-ops/git-ops.d.ts.map +1 -1
  30. package/dist/scripts/shared/git-ops/git-ops.js +26 -0
  31. package/dist/scripts/shared/git-ops/git-ops.js.map +1 -1
  32. package/dist/scripts/shared/preflight/preflight.d.ts.map +1 -1
  33. package/dist/scripts/shared/preflight/preflight.js +15 -3
  34. package/dist/scripts/shared/preflight/preflight.js.map +1 -1
  35. package/dist/scripts/shared/progress/progress.d.ts +2 -1
  36. package/dist/scripts/shared/progress/progress.d.ts.map +1 -1
  37. package/dist/scripts/shared/progress/progress.js +29 -13
  38. package/dist/scripts/shared/progress/progress.js.map +1 -1
  39. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts +12 -0
  40. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts.map +1 -1
  41. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js +51 -1
  42. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js.map +1 -1
  43. package/dist/scripts/shared/pull-request/github/github.d.ts +26 -2
  44. package/dist/scripts/shared/pull-request/github/github.d.ts.map +1 -1
  45. package/dist/scripts/shared/pull-request/github/github.js +102 -9
  46. package/dist/scripts/shared/pull-request/github/github.js.map +1 -1
  47. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts +30 -2
  48. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts.map +1 -1
  49. package/dist/scripts/shared/pull-request/gitlab/gitlab.js +70 -4
  50. package/dist/scripts/shared/pull-request/gitlab/gitlab.js.map +1 -1
  51. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts.map +1 -1
  52. package/dist/scripts/shared/pull-request/pr-body/pr-body.js +6 -1
  53. package/dist/scripts/shared/pull-request/pr-body/pr-body.js.map +1 -1
  54. package/dist/types/remote.d.ts +2 -0
  55. package/dist/types/remote.d.ts.map +1 -1
  56. package/package.json +1 -1
  57. package/src/roles/planner/commands/approve-plan.md +7 -0
  58. package/src/roles/planner/commands/plan.md +11 -1
  59. package/src/roles/planner/workflows/approve-plan.md +478 -0
  60. package/src/roles/planner/workflows/plan.md +171 -49
  61. package/src/roles/reviewer/workflows/logs.md +7 -3
  62. package/src/roles/setup/commands/help.md +3 -2
  63. package/src/roles/setup/workflows/init.md +53 -2
  64. package/src/roles/setup/workflows/scaffold.md +23 -0
  65. package/src/roles/setup/workflows/settings.md +21 -1
  66. package/src/templates/CLAUDE.md +2 -0
  67. package/src/roles/planner/commands/approve.md +0 -7
  68. 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
 
@@ -504,13 +504,13 @@ Note: as more roles are added in future versions, they appear as additional numb
504
504
 
505
505
  ---
506
506
 
507
- ## Step 4d (Jira only, if Planner role selected): Planning queue status
507
+ ## Step 4d (if Planner role selected): Planning queue config
508
508
 
509
509
  Only ask this if the user selected Planner in Step 4c above (or if re-running init and `CLANCY_ROLES` already includes `planner`).
510
510
 
511
511
  If the planner role is not enabled, skip this step entirely.
512
512
 
513
- Output:
513
+ **Jira:** Output:
514
514
 
515
515
  ```
516
516
  The Planner role picks tickets from a separate queue for planning.
@@ -524,6 +524,57 @@ Which Jira status should Clancy pick planning tickets from?
524
524
  If [1]: store `CLANCY_PLAN_STATUS="Backlog"` in `.clancy/.env`.
525
525
  If [2]: prompt for the value, store as `CLANCY_PLAN_STATUS` in `.clancy/.env`. Wrap in double quotes.
526
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
+
527
578
  ---
528
579
 
529
580
  ## Step 5 — Optional enhancements
@@ -407,6 +407,14 @@ MAX_ITERATIONS=5
407
407
  # Only used if Planner role is enabled via CLANCY_ROLES
408
408
  # CLANCY_PLAN_STATUS="Backlog"
409
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
+
410
418
  # ─── Optional: Notifications ──────────────────────────────────────────────────
411
419
  # Webhook URL for Slack or Teams notifications on ticket completion
412
420
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
@@ -469,6 +477,11 @@ MAX_ITERATIONS=20
469
477
  # next run. No configuration needed.
470
478
  # CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
471
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
+
472
485
  # ─── Optional: Notifications ──────────────────────────────────────────────────
473
486
  # Webhook URL for Slack or Teams notifications on ticket completion
474
487
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
@@ -490,6 +503,11 @@ LINEAR_TEAM_ID=your-team-uuid
490
503
  # Create the label in Linear first, then add it to any issue you want Clancy to pick up.
491
504
  # CLANCY_LABEL=clancy
492
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
+
493
511
  # ─── Git ──────────────────────────────────────────────────────────────────────
494
512
  # Base integration branch. Clancy branches from here when an issue has no parent.
495
513
  # When an issue has a parent, Clancy auto-creates epic/{key} from this branch.
@@ -541,6 +559,11 @@ MAX_ITERATIONS=20
541
559
  # CLANCY_GIT_PLATFORM=gitlab # override auto-detection (github/gitlab/bitbucket)
542
560
  # CLANCY_GIT_API_URL=https://gitlab.example.com/api/v4 # self-hosted git API base URL
543
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
+
544
567
  # ─── Optional: Notifications ──────────────────────────────────────────────────
545
568
  # Webhook URL for Slack or Teams notifications on ticket completion
546
569
  # CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
@@ -80,6 +80,8 @@ Planner
80
80
  [P1] Plan label {CLANCY_PLAN_LABEL:-needs-refinement}
81
81
  {If Linear:}
82
82
  [P1] Plan state type {CLANCY_PLAN_STATE_TYPE:-backlog}
83
+ {If Jira:}
84
+ [P2] Post-approval {CLANCY_STATUS_PLANNED if set, else "off"}
83
85
 
84
86
  Git Host (PR creation)
85
87
  [H1] Git host token {platform: GitHub/GitLab/Bitbucket or "not set"}
@@ -342,7 +344,7 @@ If [2]: remove `CLANCY_STATUS_REVIEW` from `.clancy/.env`.
342
344
  ```
343
345
  Planner role — currently: {enabled / disabled}
344
346
  The Planner refines vague backlog tickets into structured implementation plans.
345
- Commands: /clancy:plan, /clancy:approve
347
+ Commands: /clancy:plan, /clancy:approve-plan
346
348
 
347
349
  [1] Enable
348
350
  [2] Disable
@@ -409,6 +411,24 @@ If [3]: prompt `What state type should /clancy:plan fetch from?` then write `CLA
409
411
 
410
412
  ---
411
413
 
414
+ ### [P2] Post-approval transition (Jira only)
415
+
416
+ Only shown when Planner is enabled and board is Jira.
417
+
418
+ ```
419
+ Post-approval transition — current: {value or "off"}
420
+ After approving a plan, transition the ticket to this status.
421
+
422
+ [1] Set status name
423
+ [2] Off (move manually)
424
+ [3] Cancel
425
+ ```
426
+
427
+ If [1]: prompt `What status should Clancy transition to after approving a plan? (e.g. To Do, Ready)` then write `CLANCY_STATUS_PLANNED=<value>` to `.clancy/.env`. Wrap in double quotes.
428
+ If [2]: remove `CLANCY_STATUS_PLANNED` from `.clancy/.env`.
429
+
430
+ ---
431
+
412
432
  ### [H1] Git host token
413
433
 
414
434
  Only shown for Jira and Linear boards. GitHub Issues users already have `GITHUB_TOKEN` for PR creation.
@@ -54,7 +54,9 @@ Log completed tickets to `.clancy/progress.txt`:
54
54
  `YYYY-MM-DD HH:MM | TICKET-KEY | Summary | DONE`
55
55
 
56
56
  Planning entries use: `YYYY-MM-DD HH:MM | TICKET-KEY | PLAN | S/M/L`
57
+ Revised plan entries use: `YYYY-MM-DD HH:MM | TICKET-KEY | REVISED | S/M/L`
57
58
  Approval entries use: `YYYY-MM-DD HH:MM | TICKET-KEY | APPROVE | —`
59
+ Failed comment posts use: `YYYY-MM-DD HH:MM | TICKET-KEY | POST_FAILED | {reason}`
58
60
 
59
61
  ### Design context
60
62
  When a ticket description contains a Figma URL, fetch design context before implementing.
@@ -1,7 +0,0 @@
1
- # /clancy:approve
2
-
3
- Promote an approved Clancy plan to the ticket description. Requires a ticket key argument (e.g. `/clancy:approve PROJ-123`).
4
-
5
- @.claude/clancy/workflows/approve.md
6
-
7
- Follow the approve workflow above. Fetch the plan comment, confirm with the user, and append it to the ticket description.