chief-clancy 0.6.0 → 0.7.1

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 (181) hide show
  1. package/README.md +3 -2
  2. package/dist/bundle/clancy-afk.js +6 -2
  3. package/dist/bundle/clancy-once.js +49 -48
  4. package/dist/installer/hook-installer/hook-installer.d.ts +2 -0
  5. package/dist/installer/hook-installer/hook-installer.d.ts.map +1 -1
  6. package/dist/installer/hook-installer/hook-installer.js +36 -1
  7. package/dist/installer/hook-installer/hook-installer.js.map +1 -1
  8. package/dist/installer/install.js +8 -0
  9. package/dist/installer/install.js.map +1 -1
  10. package/hooks/clancy-branch-guard.js +129 -0
  11. package/hooks/clancy-context-monitor.js +134 -46
  12. package/hooks/clancy-post-compact.js +53 -0
  13. package/hooks/package.json +3 -0
  14. package/package.json +7 -3
  15. package/src/agents/verification-gate.md +128 -0
  16. package/src/roles/setup/workflows/init.md +45 -0
  17. package/src/roles/setup/workflows/scaffold.md +30 -0
  18. package/src/roles/setup/workflows/settings.md +56 -0
  19. package/src/templates/.env.example.github +19 -1
  20. package/src/templates/.env.example.jira +25 -1
  21. package/src/templates/.env.example.linear +19 -1
  22. package/dist/schemas/bitbucket-pr.d.ts +0 -137
  23. package/dist/schemas/bitbucket-pr.d.ts.map +0 -1
  24. package/dist/schemas/bitbucket-pr.js +0 -75
  25. package/dist/schemas/bitbucket-pr.js.map +0 -1
  26. package/dist/schemas/env.d.ts +0 -150
  27. package/dist/schemas/env.d.ts.map +0 -1
  28. package/dist/schemas/env.js +0 -63
  29. package/dist/schemas/env.js.map +0 -1
  30. package/dist/schemas/github-issues.d.ts +0 -105
  31. package/dist/schemas/github-issues.d.ts.map +0 -1
  32. package/dist/schemas/github-issues.js +0 -54
  33. package/dist/schemas/github-issues.js.map +0 -1
  34. package/dist/schemas/gitlab-mr.d.ts +0 -73
  35. package/dist/schemas/gitlab-mr.d.ts.map +0 -1
  36. package/dist/schemas/gitlab-mr.js +0 -33
  37. package/dist/schemas/gitlab-mr.js.map +0 -1
  38. package/dist/schemas/jira.d.ts +0 -59
  39. package/dist/schemas/jira.d.ts.map +0 -1
  40. package/dist/schemas/jira.js +0 -56
  41. package/dist/schemas/jira.js.map +0 -1
  42. package/dist/schemas/linear.d.ts +0 -108
  43. package/dist/schemas/linear.d.ts.map +0 -1
  44. package/dist/schemas/linear.js +0 -84
  45. package/dist/schemas/linear.js.map +0 -1
  46. package/dist/scripts/afk/afk.d.ts +0 -21
  47. package/dist/scripts/afk/afk.d.ts.map +0 -1
  48. package/dist/scripts/afk/afk.js +0 -118
  49. package/dist/scripts/afk/afk.js.map +0 -1
  50. package/dist/scripts/board/github/github.d.ts +0 -104
  51. package/dist/scripts/board/github/github.d.ts.map +0 -1
  52. package/dist/scripts/board/github/github.js +0 -291
  53. package/dist/scripts/board/github/github.js.map +0 -1
  54. package/dist/scripts/board/jira/jira.d.ts +0 -139
  55. package/dist/scripts/board/jira/jira.d.ts.map +0 -1
  56. package/dist/scripts/board/jira/jira.js +0 -378
  57. package/dist/scripts/board/jira/jira.js.map +0 -1
  58. package/dist/scripts/board/linear/linear.d.ts +0 -129
  59. package/dist/scripts/board/linear/linear.d.ts.map +0 -1
  60. package/dist/scripts/board/linear/linear.js +0 -393
  61. package/dist/scripts/board/linear/linear.js.map +0 -1
  62. package/dist/scripts/once/board-ops/board-ops.d.ts +0 -26
  63. package/dist/scripts/once/board-ops/board-ops.d.ts.map +0 -1
  64. package/dist/scripts/once/board-ops/board-ops.js +0 -113
  65. package/dist/scripts/once/board-ops/board-ops.js.map +0 -1
  66. package/dist/scripts/once/deliver/deliver.d.ts +0 -37
  67. package/dist/scripts/once/deliver/deliver.d.ts.map +0 -1
  68. package/dist/scripts/once/deliver/deliver.js +0 -236
  69. package/dist/scripts/once/deliver/deliver.js.map +0 -1
  70. package/dist/scripts/once/fetch-ticket/fetch-ticket.d.ts +0 -22
  71. package/dist/scripts/once/fetch-ticket/fetch-ticket.d.ts.map +0 -1
  72. package/dist/scripts/once/fetch-ticket/fetch-ticket.js +0 -123
  73. package/dist/scripts/once/fetch-ticket/fetch-ticket.js.map +0 -1
  74. package/dist/scripts/once/git-token/git-token.d.ts +0 -13
  75. package/dist/scripts/once/git-token/git-token.d.ts.map +0 -1
  76. package/dist/scripts/once/git-token/git-token.js +0 -30
  77. package/dist/scripts/once/git-token/git-token.js.map +0 -1
  78. package/dist/scripts/once/once.d.ts +0 -12
  79. package/dist/scripts/once/once.d.ts.map +0 -1
  80. package/dist/scripts/once/once.js +0 -356
  81. package/dist/scripts/once/once.js.map +0 -1
  82. package/dist/scripts/once/pr-creation/pr-creation.d.ts +0 -11
  83. package/dist/scripts/once/pr-creation/pr-creation.d.ts.map +0 -1
  84. package/dist/scripts/once/pr-creation/pr-creation.js +0 -50
  85. package/dist/scripts/once/pr-creation/pr-creation.js.map +0 -1
  86. package/dist/scripts/once/rework/rework.d.ts +0 -32
  87. package/dist/scripts/once/rework/rework.d.ts.map +0 -1
  88. package/dist/scripts/once/rework/rework.js +0 -208
  89. package/dist/scripts/once/rework/rework.js.map +0 -1
  90. package/dist/scripts/once/types/types.d.ts +0 -13
  91. package/dist/scripts/once/types/types.d.ts.map +0 -1
  92. package/dist/scripts/once/types/types.js +0 -2
  93. package/dist/scripts/once/types/types.js.map +0 -1
  94. package/dist/scripts/shared/branch/branch.d.ts +0 -50
  95. package/dist/scripts/shared/branch/branch.d.ts.map +0 -1
  96. package/dist/scripts/shared/branch/branch.js +0 -61
  97. package/dist/scripts/shared/branch/branch.js.map +0 -1
  98. package/dist/scripts/shared/claude-cli/claude-cli.d.ts +0 -31
  99. package/dist/scripts/shared/claude-cli/claude-cli.d.ts.map +0 -1
  100. package/dist/scripts/shared/claude-cli/claude-cli.js +0 -60
  101. package/dist/scripts/shared/claude-cli/claude-cli.js.map +0 -1
  102. package/dist/scripts/shared/env-schema/env-schema.d.ts +0 -27
  103. package/dist/scripts/shared/env-schema/env-schema.d.ts.map +0 -1
  104. package/dist/scripts/shared/env-schema/env-schema.js +0 -47
  105. package/dist/scripts/shared/env-schema/env-schema.js.map +0 -1
  106. package/dist/scripts/shared/feasibility/feasibility.d.ts +0 -30
  107. package/dist/scripts/shared/feasibility/feasibility.d.ts.map +0 -1
  108. package/dist/scripts/shared/feasibility/feasibility.js +0 -68
  109. package/dist/scripts/shared/feasibility/feasibility.js.map +0 -1
  110. package/dist/scripts/shared/format/format.d.ts +0 -11
  111. package/dist/scripts/shared/format/format.d.ts.map +0 -1
  112. package/dist/scripts/shared/format/format.js +0 -18
  113. package/dist/scripts/shared/format/format.js.map +0 -1
  114. package/dist/scripts/shared/git-ops/git-ops.d.ts +0 -90
  115. package/dist/scripts/shared/git-ops/git-ops.d.ts.map +0 -1
  116. package/dist/scripts/shared/git-ops/git-ops.js +0 -190
  117. package/dist/scripts/shared/git-ops/git-ops.js.map +0 -1
  118. package/dist/scripts/shared/http/http.d.ts +0 -54
  119. package/dist/scripts/shared/http/http.d.ts.map +0 -1
  120. package/dist/scripts/shared/http/http.js +0 -76
  121. package/dist/scripts/shared/http/http.js.map +0 -1
  122. package/dist/scripts/shared/notify/notify.d.ts +0 -46
  123. package/dist/scripts/shared/notify/notify.d.ts.map +0 -1
  124. package/dist/scripts/shared/notify/notify.js +0 -88
  125. package/dist/scripts/shared/notify/notify.js.map +0 -1
  126. package/dist/scripts/shared/preflight/preflight.d.ts +0 -40
  127. package/dist/scripts/shared/preflight/preflight.d.ts.map +0 -1
  128. package/dist/scripts/shared/preflight/preflight.js +0 -96
  129. package/dist/scripts/shared/preflight/preflight.js.map +0 -1
  130. package/dist/scripts/shared/progress/progress.d.ts +0 -75
  131. package/dist/scripts/shared/progress/progress.d.ts.map +0 -1
  132. package/dist/scripts/shared/progress/progress.js +0 -210
  133. package/dist/scripts/shared/progress/progress.js.map +0 -1
  134. package/dist/scripts/shared/prompt/prompt.d.ts +0 -58
  135. package/dist/scripts/shared/prompt/prompt.d.ts.map +0 -1
  136. package/dist/scripts/shared/prompt/prompt.js +0 -123
  137. package/dist/scripts/shared/prompt/prompt.js.map +0 -1
  138. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts +0 -82
  139. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts.map +0 -1
  140. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js +0 -301
  141. package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js.map +0 -1
  142. package/dist/scripts/shared/pull-request/github/github.d.ts +0 -72
  143. package/dist/scripts/shared/pull-request/github/github.d.ts.map +0 -1
  144. package/dist/scripts/shared/pull-request/github/github.js +0 -226
  145. package/dist/scripts/shared/pull-request/github/github.js.map +0 -1
  146. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts +0 -74
  147. package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts.map +0 -1
  148. package/dist/scripts/shared/pull-request/gitlab/gitlab.js +0 -220
  149. package/dist/scripts/shared/pull-request/gitlab/gitlab.js.map +0 -1
  150. package/dist/scripts/shared/pull-request/post-pr/post-pr.d.ts +0 -31
  151. package/dist/scripts/shared/pull-request/post-pr/post-pr.d.ts.map +0 -1
  152. package/dist/scripts/shared/pull-request/post-pr/post-pr.js +0 -61
  153. package/dist/scripts/shared/pull-request/post-pr/post-pr.js.map +0 -1
  154. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts +0 -40
  155. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts.map +0 -1
  156. package/dist/scripts/shared/pull-request/pr-body/pr-body.js +0 -84
  157. package/dist/scripts/shared/pull-request/pr-body/pr-body.js.map +0 -1
  158. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts +0 -23
  159. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts.map +0 -1
  160. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js +0 -30
  161. package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js.map +0 -1
  162. package/dist/scripts/shared/remote/remote.d.ts +0 -41
  163. package/dist/scripts/shared/remote/remote.d.ts.map +0 -1
  164. package/dist/scripts/shared/remote/remote.js +0 -227
  165. package/dist/scripts/shared/remote/remote.js.map +0 -1
  166. package/dist/types/board.d.ts +0 -13
  167. package/dist/types/board.d.ts.map +0 -1
  168. package/dist/types/board.js +0 -5
  169. package/dist/types/board.js.map +0 -1
  170. package/dist/types/index.d.ts +0 -4
  171. package/dist/types/index.d.ts.map +0 -1
  172. package/dist/types/index.js +0 -2
  173. package/dist/types/index.js.map +0 -1
  174. package/dist/types/remote.d.ts +0 -55
  175. package/dist/types/remote.d.ts.map +0 -1
  176. package/dist/types/remote.js +0 -5
  177. package/dist/types/remote.js.map +0 -1
  178. package/dist/utils/parse-json/parse-json.d.ts +0 -20
  179. package/dist/utils/parse-json/parse-json.d.ts.map +0 -1
  180. package/dist/utils/parse-json/parse-json.js +0 -27
  181. package/dist/utils/parse-json/parse-json.js.map +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Autonomous, board-driven development for Claude Code.**
4
4
 
5
- [![npm](https://img.shields.io/npm/v/chief-clancy?style=for-the-badge&color=cb3837)](https://www.npmjs.com/package/chief-clancy) [![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](./LICENSE) [![Tests](https://img.shields.io/badge/tests-579%20passing-brightgreen?style=for-the-badge)](docs/TESTING.md) [![GitHub Stars](https://img.shields.io/github/stars/Pushedskydiver/clancy?style=for-the-badge)](https://github.com/Pushedskydiver/clancy/stargazers)
5
+ [![npm](https://img.shields.io/npm/v/chief-clancy?style=for-the-badge&color=cb3837)](https://www.npmjs.com/package/chief-clancy) [![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](./LICENSE) [![Tests](https://img.shields.io/badge/tests-853%20passing-brightgreen?style=for-the-badge)](docs/TESTING.md) [![GitHub Stars](https://img.shields.io/github/stars/Pushedskydiver/clancy?style=for-the-badge)](https://github.com/Pushedskydiver/clancy/stargazers)
6
6
 
7
7
  > [!WARNING]
8
8
  > Clancy is in early development. Expect bugs, breaking changes, and rough edges. If you hit an issue, please [open a bug report](https://github.com/Pushedskydiver/clancy/issues/new).
@@ -25,13 +25,14 @@ Named after Chief Clancy Wiggum (The Simpsons) — built on the [Ralph technique
25
25
 
26
26
  ## What it does
27
27
 
28
- Clancy does five things:
28
+ Clancy does six things:
29
29
 
30
30
  1. **Scaffolds itself** into a project — scripts, docs, CLAUDE.md, .clancy/.env
31
31
  2. **Scans your codebase** with 5 parallel specialist agents and writes 10 structured docs that Claude reads before every run
32
32
  3. **Writes strategy briefs** — interviews you (or runs a devil's advocate AI-grill in AFK mode), decomposes work into vertical slices with HITL/AFK classification, and creates board tickets with blocking dependencies
33
33
  4. **Plans tickets** — fetches backlog tickets, explores the codebase, and generates structured implementation plans posted as comments for human review
34
34
  5. **Runs autonomously** — picking one ticket per loop from your Kanban board (skipping blocked candidates), implementing it, committing, and creating a PR (targeting an epic branch for parented tickets, or the base branch for standalone tickets)
35
+ 6. **Verifies before delivery** — runs lint, test, and typecheck via verification gates with self-healing retry, guards against force push and destructive resets, and recovers from crashes via lock file detection
35
36
 
36
37
  Brief → approve → plan → implement. One ticket per run. Fresh context window every iteration. No context rot.
37
38
 
@@ -1,2 +1,6 @@
1
- import{spawnSync as k}from"node:child_process";import{existsSync as h}from"node:fs";import{dirname as w,join as T,resolve as y}from"node:path";import{setTimeout as S}from"node:timers/promises";import{fileURLToPath as g}from"node:url";function c(o){let t=Math.floor(o/1e3);if(t<60)return`${t}s`;let r=Math.floor(t/60),s=t%60;return s>0?`${r}m ${s}s`:`${r}m`}var e=o=>`\x1B[2m${o}\x1B[0m`,a=o=>`\x1B[1m${o}\x1B[0m`;var u=o=>`\x1B[32m${o}\x1B[0m`,p=o=>`\x1B[31m${o}\x1B[0m`;var m={noTickets:/No tickets found|No issues found|All done/,skipped:/Ticket skipped/,preflightFail:/^✗ /m};function A(o){return m.noTickets.test(o)?{stop:!0,reason:"No more tickets \u2014 all done"}:m.skipped.test(o)?{stop:!0,reason:"Ticket was skipped \u2014 update the ticket and re-run"}:m.preflightFail.test(o)?{stop:!0,reason:"Preflight check failed"}:{stop:!1}}async function D(o,t=5){let r=T(o,"clancy-once.js");if(!h(r)){console.error(p("\u2717 clancy-once.js not found in"),o);return}console.log(e("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")),console.log(e("\u2502")+a(" \u{1F916} Clancy \u2014 AFK mode ")+e("\u2502")),console.log(e("\u2502")+e(` "I'm on it. Proceed to the abandoned warehouse." `)+e("\u2502")),console.log(e("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));let s=Date.now();for(let n=1;n<=t;n++){let x=Date.now();console.log(""),console.log(a(`\u{1F501} Iteration ${n}/${t}`));let i=k("node",[r],{encoding:"utf8",stdio:["inherit","pipe","inherit"],cwd:process.cwd(),env:{...process.env,CLANCY_AFK_MODE:"1"}}),l=i.stdout??"";l&&process.stdout.write(l);let d=c(Date.now()-x);if(i.error){console.error(p(`\u2717 Failed to run clancy-once: ${i.error.message}`));return}let f=A(l);if(f.stop){let b=c(Date.now()-s);console.log(""),console.log(e(` Iteration ${n} took ${d}`)),console.log(`
2
- ${f.reason}`),console.log(e(` Total: ${n} iteration${n>1?"s":""} in ${b}`));return}console.log(e(` Iteration ${n} took ${d}`)),n<t&&await S(2e3)}let $=c(Date.now()-s);console.log(""),console.log(u(`\u{1F3C1} Completed ${t} iterations`)+e(` (${$})`)),console.log(e(` "That's some good police work."`)),console.log(e(" Run clancy-afk again to continue."))}if(process.argv[1]&&g(import.meta.url)===y(process.argv[1])){let o=w(g(import.meta.url)),t=parseInt(process.env.MAX_ITERATIONS??"5",10)||5;D(o,t)}export{A as checkStopCondition,D as runAfkLoop};
1
+ import{spawnSync as J}from"node:child_process";import{existsSync as X}from"node:fs";import{dirname as Z,join as q,resolve as z}from"node:path";import{setTimeout as G}from"node:timers/promises";import{fileURLToPath as M}from"node:url";function $(t){let o=Math.floor(t/1e3);if(o<60)return`${o}s`;let r=Math.floor(o/60),i=o%60;if(r<60)return i>0?`${r}m ${i}s`:`${r}m`;let u=Math.floor(r/60),c=r%60;return c>0?`${u}h ${c}m`:`${u}h`}function L(t){return t.includes("hooks.slack.com")}function O(t){return JSON.stringify({text:t})}function _(t){return JSON.stringify({type:"message",attachments:[{contentType:"application/vnd.microsoft.card.adaptive",content:{$schema:"http://adaptivecards.io/schemas/adaptive-card.json",type:"AdaptiveCard",version:"1.4",body:[{type:"TextBlock",text:t,wrap:!0}]}}]})}async function C(t,o){let r=L(t)?O(o):_(o);try{let i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:r});i.ok||console.warn(`\u26A0 Notification failed: HTTP ${i.status}`)}catch{console.warn("\u26A0 Notification failed: could not reach webhook")}}var p=t=>`\x1B[2m${t}\x1B[0m`,x=t=>`\x1B[1m${t}\x1B[0m`;var D=t=>`\x1B[32m${t}\x1B[0m`,w=t=>`\x1B[31m${t}\x1B[0m`;import{mkdirSync as j,readFileSync as B,writeFileSync as W}from"node:fs";import{join as E}from"node:path";import{appendFileSync as rt,mkdirSync as it,readFileSync as U}from"node:fs";import{dirname as at,join as K}from"node:path";function R(t){let o=K(t,".clancy","progress.txt"),r;try{r=U(o,"utf8")}catch{return[]}let i=[];for(let u of r.split(`
2
+ `)){let c=u.trim();if(!c)continue;let s=c.split(" | ");if(s.length<4)continue;let l=s[0];if(s[1]==="BRIEF"||s[1]==="APPROVE_BRIEF"){i.push({timestamp:l,key:s[2],summary:s.slice(3).join(" | "),status:s[1]});continue}let f=s[1],a,h,y,k=[];for(let g=2;g<s.length;g++){let m=s[g],S=m.match(/^pr:(\d+)$/),n=m.match(/^parent:(.+)$/);S?h=parseInt(S[1],10):n?y=n[1]:g>=3&&!a&&m===m.toUpperCase()&&m.length>1?a=m:k.push(m)}a&&(a==="APPROVE"&&(a="APPROVE_PLAN"),i.push({timestamp:l,key:f,summary:k.join(" | "),status:a,...h!=null&&{prNumber:h},...y!=null&&{parent:y}}))}return i}function H(t,o){let r=E(t,".clancy","costs.log"),i;try{i=B(r,"utf8")}catch{return[]}let u=[];for(let c of i.split(`
3
+ `)){let s=c.trim();if(!s)continue;let l=s.split(" | ");if(l.length<4)continue;let f=l[0],a=new Date(f).getTime();Number.isNaN(a)||a<o||u.push({timestamp:f,key:l[1],duration:l[2],tokens:l[3]})}return u}function Y(t){return/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(t)?new Date(t.replace(" ","T")+":00Z").getTime():NaN}var A=new Set(["DONE","PR_CREATED","PUSHED","EPIC_PR_CREATED","RESUMED"]),V=new Set(["SKIPPED","PUSH_FAILED","TIME_LIMIT"]);function F(t,o,r){let i=Math.floor(o/6e4)*6e4,c=R(t).filter(e=>{let d=Y(e.timestamp);return!Number.isNaN(d)&&d>=i}),s=H(t,o),l=new Map;for(let e of s)l.set(e.key,e);let f=new Map;for(let e of c)f.set(e.key,e);let a=[];for(let e of f.values()){let d=l.get(e.key);a.push({key:e.key,summary:e.summary,status:e.status,...e.prNumber!=null&&{prNumber:e.prNumber},...d&&{duration:d.duration,tokens:d.tokens}})}let h=a.filter(e=>A.has(e.status)),y=a.filter(e=>V.has(e.status)),k=$(r-o),g=0;for(let e of s){let d=e.tokens.match(/~(\d[\d,]*)/);d&&(g+=parseInt(d[1].replace(/,/g,""),10))}let m=new Date(o),S=`${m.getUTCFullYear()}-${String(m.getUTCMonth()+1).padStart(2,"0")}-${String(m.getUTCDate()).padStart(2,"0")}`,n=[];n.push(`# AFK Session Report \u2014 ${S}`),n.push(""),n.push("## Summary"),n.push(`- Tickets completed: ${h.length}`),n.push(`- Tickets failed: ${y.length}`),n.push(`- Total duration: ${k}`),g>0&&n.push(`- Estimated token usage: ${g.toLocaleString("en-US")}`),n.push(""),n.push("## Tickets"),a.length===0&&(n.push(""),n.push("No tickets were processed in this session."));for(let e of a){let I=A.has(e.status)?"\u2713":"\u2717";n.push(""),n.push(`### ${I} ${e.key} \u2014 ${e.summary}`),e.duration&&n.push(`- Duration: ${e.duration}`),e.tokens&&n.push(`- Tokens: ${e.tokens}`),e.prNumber!=null&&n.push(`- PR: #${e.prNumber}`),n.push(`- Status: ${e.status}`)}let T=a.filter(e=>e.prNumber!=null).map(e=>`#${e.prNumber}`),b=y.map(e=>e.key);if(T.length>0||b.length>0){n.push(""),n.push("## Next Steps"),T.length>0&&n.push(`- Review PRs ${T.join(", ")}`);for(let e of b)n.push(`- ${e} needs manual intervention`)}n.push("");let N=n.join(`
4
+ `);try{let e=E(t,".clancy","session-report.md");j(E(t,".clancy"),{recursive:!0}),W(e,N,"utf8")}catch{}return N}var P={noTickets:/No tickets found|No issues found|All done/,skipped:/Ticket skipped/,preflightFail:/^✗ /m};function Q(t){return P.noTickets.test(t)?{stop:!0,reason:"No more tickets \u2014 all done"}:P.skipped.test(t)?{stop:!0,reason:"Ticket was skipped \u2014 update the ticket and re-run"}:P.preflightFail.test(t)?{stop:!0,reason:"Preflight check failed"}:{stop:!1}}async function tt(t,o=5){let r=q(t,"clancy-once.js");if(!X(r)){console.error(w("\u2717 clancy-once.js not found in"),t);return}console.log(p("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")),console.log(p("\u2502")+x(" \u{1F916} Clancy \u2014 AFK mode ")+p("\u2502")),console.log(p("\u2502")+p(` "I'm on it. Proceed to the abandoned warehouse." `)+p("\u2502")),console.log(p("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));let i=Date.now();for(let c=1;c<=o;c++){let s=Date.now();console.log(""),console.log(x(`\u{1F501} Iteration ${c}/${o}`));let l=J("node",[r],{encoding:"utf8",stdio:["inherit","pipe","inherit"],cwd:process.cwd(),env:{...process.env,CLANCY_AFK_MODE:"1"}}),f=l.stdout??"";f&&process.stdout.write(f);let a=$(Date.now()-s);if(l.error){console.error(w(`\u2717 Failed to run clancy-once: ${l.error.message}`));return}let h=Q(f);if(h.stop){let y=$(Date.now()-i);console.log(""),console.log(p(` Iteration ${c} took ${a}`)),console.log(`
5
+ ${h.reason}`),console.log(p(` Total: ${c} iteration${c>1?"s":""} in ${y}`)),v(i);return}console.log(p(` Iteration ${c} took ${a}`)),c<o&&await G(2e3)}let u=$(Date.now()-i);console.log(""),console.log(D(`\u{1F3C1} Completed ${o} iterations`)+p(` (${u})`)),console.log(p(` "That's some good police work."`)),console.log(p(" Run clancy-afk again to continue.")),v(i)}function v(t){try{let o=F(process.cwd(),t,Date.now());console.log(""),console.log(p("\u2500\u2500\u2500 Session Report \u2500\u2500\u2500")),console.log(o);let r=process.env.CLANCY_NOTIFY_WEBHOOK;if(r){let c=`Clancy AFK: ${o.split(`
6
+ `).filter(s=>s.startsWith("- Tickets")||s.startsWith("- Total")).join(". ")}. Report: .clancy/session-report.md`;C(r,c).catch(()=>{})}}catch{}}if(process.argv[1]&&M(import.meta.url)===z(process.argv[1])){let t=Z(M(import.meta.url)),o=parseInt(process.env.MAX_ITERATIONS??"5",10)||5;tt(t,o)}export{Q as checkStopCondition,tt as runAfkLoop};