@bradygaster/squad-cli 0.9.1 → 0.9.2-insider.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 (320) hide show
  1. package/README.md +329 -329
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +10 -10
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/config.d.ts +12 -0
  6. package/dist/cli/commands/config.d.ts.map +1 -0
  7. package/dist/cli/commands/config.js +157 -0
  8. package/dist/cli/commands/config.js.map +1 -0
  9. package/dist/cli/commands/consult.d.ts.map +1 -1
  10. package/dist/cli/commands/consult.js +9 -4
  11. package/dist/cli/commands/consult.js.map +1 -1
  12. package/dist/cli/commands/copilot.d.ts.map +1 -1
  13. package/dist/cli/commands/copilot.js +8 -7
  14. package/dist/cli/commands/copilot.js.map +1 -1
  15. package/dist/cli/commands/doctor.d.ts.map +1 -1
  16. package/dist/cli/commands/doctor.js +50 -17
  17. package/dist/cli/commands/doctor.js.map +1 -1
  18. package/dist/cli/commands/economy.d.ts.map +1 -1
  19. package/dist/cli/commands/economy.js +3 -2
  20. package/dist/cli/commands/economy.js.map +1 -1
  21. package/dist/cli/commands/export.d.ts.map +1 -1
  22. package/dist/cli/commands/export.js +22 -16
  23. package/dist/cli/commands/export.js.map +1 -1
  24. package/dist/cli/commands/extract.d.ts.map +1 -1
  25. package/dist/cli/commands/extract.js +14 -10
  26. package/dist/cli/commands/extract.js.map +1 -1
  27. package/dist/cli/commands/import.d.ts.map +1 -1
  28. package/dist/cli/commands/import.js +21 -18
  29. package/dist/cli/commands/import.js.map +1 -1
  30. package/dist/cli/commands/init-remote.d.ts.map +1 -1
  31. package/dist/cli/commands/init-remote.js +7 -6
  32. package/dist/cli/commands/init-remote.js.map +1 -1
  33. package/dist/cli/commands/link.d.ts.map +1 -1
  34. package/dist/cli/commands/link.js +11 -10
  35. package/dist/cli/commands/link.js.map +1 -1
  36. package/dist/cli/commands/migrate.d.ts.map +1 -1
  37. package/dist/cli/commands/migrate.js +19 -18
  38. package/dist/cli/commands/migrate.js.map +1 -1
  39. package/dist/cli/commands/personal.d.ts.map +1 -1
  40. package/dist/cli/commands/personal.js +57 -65
  41. package/dist/cli/commands/personal.js.map +1 -1
  42. package/dist/cli/commands/plugin.d.ts.map +1 -1
  43. package/dist/cli/commands/plugin.js +8 -7
  44. package/dist/cli/commands/plugin.js.map +1 -1
  45. package/dist/cli/commands/rc.d.ts.map +1 -1
  46. package/dist/cli/commands/rc.js +19 -12
  47. package/dist/cli/commands/rc.js.map +1 -1
  48. package/dist/cli/commands/schedule.d.ts.map +1 -1
  49. package/dist/cli/commands/schedule.js +6 -5
  50. package/dist/cli/commands/schedule.js.map +1 -1
  51. package/dist/cli/commands/start.d.ts.map +1 -1
  52. package/dist/cli/commands/start.js +18 -11
  53. package/dist/cli/commands/start.js.map +1 -1
  54. package/dist/cli/commands/streams.d.ts.map +1 -1
  55. package/dist/cli/commands/streams.js +3 -2
  56. package/dist/cli/commands/streams.js.map +1 -1
  57. package/dist/cli/commands/upstream.d.ts.map +1 -1
  58. package/dist/cli/commands/upstream.js +23 -19
  59. package/dist/cli/commands/upstream.js.map +1 -1
  60. package/dist/cli/commands/watch/capabilities/board.d.ts +22 -0
  61. package/dist/cli/commands/watch/capabilities/board.d.ts.map +1 -0
  62. package/dist/cli/commands/watch/capabilities/board.js +121 -0
  63. package/dist/cli/commands/watch/capabilities/board.js.map +1 -0
  64. package/dist/cli/commands/watch/capabilities/budget-check.d.ts +29 -0
  65. package/dist/cli/commands/watch/capabilities/budget-check.d.ts.map +1 -0
  66. package/dist/cli/commands/watch/capabilities/budget-check.js +38 -0
  67. package/dist/cli/commands/watch/capabilities/budget-check.js.map +1 -0
  68. package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts +52 -0
  69. package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts.map +1 -0
  70. package/dist/cli/commands/watch/capabilities/circuit-breaker.js +152 -0
  71. package/dist/cli/commands/watch/capabilities/circuit-breaker.js.map +1 -0
  72. package/dist/cli/commands/watch/capabilities/decision-hygiene.d.ts +14 -0
  73. package/dist/cli/commands/watch/capabilities/decision-hygiene.d.ts.map +1 -0
  74. package/dist/cli/commands/watch/capabilities/decision-hygiene.js +72 -0
  75. package/dist/cli/commands/watch/capabilities/decision-hygiene.js.map +1 -0
  76. package/dist/cli/commands/watch/capabilities/execute.d.ts +33 -0
  77. package/dist/cli/commands/watch/capabilities/execute.d.ts.map +1 -0
  78. package/dist/cli/commands/watch/capabilities/execute.js +156 -0
  79. package/dist/cli/commands/watch/capabilities/execute.js.map +1 -0
  80. package/dist/cli/commands/watch/capabilities/health-check.d.ts +29 -0
  81. package/dist/cli/commands/watch/capabilities/health-check.d.ts.map +1 -0
  82. package/dist/cli/commands/watch/capabilities/health-check.js +139 -0
  83. package/dist/cli/commands/watch/capabilities/health-check.js.map +1 -0
  84. package/dist/cli/commands/watch/capabilities/heartbeat.d.ts +48 -0
  85. package/dist/cli/commands/watch/capabilities/heartbeat.d.ts.map +1 -0
  86. package/dist/cli/commands/watch/capabilities/heartbeat.js +115 -0
  87. package/dist/cli/commands/watch/capabilities/heartbeat.js.map +1 -0
  88. package/dist/cli/commands/watch/capabilities/index.d.ts +9 -0
  89. package/dist/cli/commands/watch/capabilities/index.d.ts.map +1 -0
  90. package/dist/cli/commands/watch/capabilities/index.js +40 -0
  91. package/dist/cli/commands/watch/capabilities/index.js.map +1 -0
  92. package/dist/cli/commands/watch/capabilities/lockfile.d.ts +30 -0
  93. package/dist/cli/commands/watch/capabilities/lockfile.d.ts.map +1 -0
  94. package/dist/cli/commands/watch/capabilities/lockfile.js +100 -0
  95. package/dist/cli/commands/watch/capabilities/lockfile.js.map +1 -0
  96. package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts +30 -0
  97. package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts.map +1 -0
  98. package/dist/cli/commands/watch/capabilities/machine-capabilities.js +103 -0
  99. package/dist/cli/commands/watch/capabilities/machine-capabilities.js.map +1 -0
  100. package/dist/cli/commands/watch/capabilities/monitor-email.d.ts +14 -0
  101. package/dist/cli/commands/watch/capabilities/monitor-email.d.ts.map +1 -0
  102. package/dist/cli/commands/watch/capabilities/monitor-email.js +54 -0
  103. package/dist/cli/commands/watch/capabilities/monitor-email.js.map +1 -0
  104. package/dist/cli/commands/watch/capabilities/monitor-teams.d.ts +14 -0
  105. package/dist/cli/commands/watch/capabilities/monitor-teams.d.ts.map +1 -0
  106. package/dist/cli/commands/watch/capabilities/monitor-teams.js +55 -0
  107. package/dist/cli/commands/watch/capabilities/monitor-teams.js.map +1 -0
  108. package/dist/cli/commands/watch/capabilities/post-failure.d.ts +19 -0
  109. package/dist/cli/commands/watch/capabilities/post-failure.d.ts.map +1 -0
  110. package/dist/cli/commands/watch/capabilities/post-failure.js +58 -0
  111. package/dist/cli/commands/watch/capabilities/post-failure.js.map +1 -0
  112. package/dist/cli/commands/watch/capabilities/priority.d.ts +59 -0
  113. package/dist/cli/commands/watch/capabilities/priority.d.ts.map +1 -0
  114. package/dist/cli/commands/watch/capabilities/priority.js +101 -0
  115. package/dist/cli/commands/watch/capabilities/priority.js.map +1 -0
  116. package/dist/cli/commands/watch/capabilities/rate-pool.d.ts +67 -0
  117. package/dist/cli/commands/watch/capabilities/rate-pool.d.ts.map +1 -0
  118. package/dist/cli/commands/watch/capabilities/rate-pool.js +187 -0
  119. package/dist/cli/commands/watch/capabilities/rate-pool.js.map +1 -0
  120. package/dist/cli/commands/watch/capabilities/retro.d.ts +14 -0
  121. package/dist/cli/commands/watch/capabilities/retro.d.ts.map +1 -0
  122. package/dist/cli/commands/watch/capabilities/retro.js +81 -0
  123. package/dist/cli/commands/watch/capabilities/retro.js.map +1 -0
  124. package/dist/cli/commands/watch/capabilities/self-pull.d.ts +14 -0
  125. package/dist/cli/commands/watch/capabilities/self-pull.d.ts.map +1 -0
  126. package/dist/cli/commands/watch/capabilities/self-pull.js +33 -0
  127. package/dist/cli/commands/watch/capabilities/self-pull.js.map +1 -0
  128. package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts +23 -0
  129. package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts.map +1 -0
  130. package/dist/cli/commands/watch/capabilities/stale-reclaim.js +87 -0
  131. package/dist/cli/commands/watch/capabilities/stale-reclaim.js.map +1 -0
  132. package/dist/cli/commands/watch/capabilities/two-pass.d.ts +14 -0
  133. package/dist/cli/commands/watch/capabilities/two-pass.d.ts.map +1 -0
  134. package/dist/cli/commands/watch/capabilities/two-pass.js +66 -0
  135. package/dist/cli/commands/watch/capabilities/two-pass.js.map +1 -0
  136. package/dist/cli/commands/watch/capabilities/wave-dispatch.d.ts +14 -0
  137. package/dist/cli/commands/watch/capabilities/wave-dispatch.d.ts.map +1 -0
  138. package/dist/cli/commands/watch/capabilities/wave-dispatch.js +117 -0
  139. package/dist/cli/commands/watch/capabilities/wave-dispatch.js.map +1 -0
  140. package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts +29 -0
  141. package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts.map +1 -0
  142. package/dist/cli/commands/watch/capabilities/webhook-alerts.js +114 -0
  143. package/dist/cli/commands/watch/capabilities/webhook-alerts.js.map +1 -0
  144. package/dist/cli/commands/watch/config.d.ts +40 -0
  145. package/dist/cli/commands/watch/config.d.ts.map +1 -0
  146. package/dist/cli/commands/watch/config.js +129 -0
  147. package/dist/cli/commands/watch/config.js.map +1 -0
  148. package/dist/cli/commands/watch/index.d.ts +109 -0
  149. package/dist/cli/commands/watch/index.d.ts.map +1 -0
  150. package/dist/cli/commands/watch/index.js +757 -0
  151. package/dist/cli/commands/watch/index.js.map +1 -0
  152. package/dist/cli/commands/watch/registry.d.ts +19 -0
  153. package/dist/cli/commands/watch/registry.d.ts.map +1 -0
  154. package/dist/cli/commands/watch/registry.js +28 -0
  155. package/dist/cli/commands/watch/registry.js.map +1 -0
  156. package/dist/cli/commands/watch/types.d.ts +57 -0
  157. package/dist/cli/commands/watch/types.d.ts.map +1 -0
  158. package/dist/cli/commands/watch/types.js +8 -0
  159. package/dist/cli/commands/watch/types.js.map +1 -0
  160. package/dist/cli/core/cast.d.ts.map +1 -1
  161. package/dist/cli/core/cast.js +15 -19
  162. package/dist/cli/core/cast.js.map +1 -1
  163. package/dist/cli/core/detect-squad-dir.d.ts.map +1 -1
  164. package/dist/cli/core/detect-squad-dir.js +12 -10
  165. package/dist/cli/core/detect-squad-dir.js.map +1 -1
  166. package/dist/cli/core/email-scrub.d.ts.map +1 -1
  167. package/dist/cli/core/email-scrub.js +12 -11
  168. package/dist/cli/core/email-scrub.js.map +1 -1
  169. package/dist/cli/core/gh-cli.d.ts +13 -0
  170. package/dist/cli/core/gh-cli.d.ts.map +1 -1
  171. package/dist/cli/core/gh-cli.js +24 -0
  172. package/dist/cli/core/gh-cli.js.map +1 -1
  173. package/dist/cli/core/init.d.ts +2 -0
  174. package/dist/cli/core/init.d.ts.map +1 -1
  175. package/dist/cli/core/init.js +22 -5
  176. package/dist/cli/core/init.js.map +1 -1
  177. package/dist/cli/core/migrate-directory.d.ts.map +1 -1
  178. package/dist/cli/core/migrate-directory.js +14 -13
  179. package/dist/cli/core/migrate-directory.js.map +1 -1
  180. package/dist/cli/core/migrations.d.ts.map +1 -1
  181. package/dist/cli/core/migrations.js +22 -8
  182. package/dist/cli/core/migrations.js.map +1 -1
  183. package/dist/cli/core/nap.d.ts.map +1 -1
  184. package/dist/cli/core/nap.js +116 -49
  185. package/dist/cli/core/nap.js.map +1 -1
  186. package/dist/cli/core/project-type.d.ts.map +1 -1
  187. package/dist/cli/core/project-type.js +11 -10
  188. package/dist/cli/core/project-type.js.map +1 -1
  189. package/dist/cli/core/team-md.d.ts.map +1 -1
  190. package/dist/cli/core/team-md.js +43 -38
  191. package/dist/cli/core/team-md.js.map +1 -1
  192. package/dist/cli/core/templates.d.ts.map +1 -1
  193. package/dist/cli/core/templates.js +4 -3
  194. package/dist/cli/core/templates.js.map +1 -1
  195. package/dist/cli/core/upgrade.d.ts.map +1 -1
  196. package/dist/cli/core/upgrade.js +68 -55
  197. package/dist/cli/core/upgrade.js.map +1 -1
  198. package/dist/cli/core/version.d.ts.map +1 -1
  199. package/dist/cli/core/version.js +8 -7
  200. package/dist/cli/core/version.js.map +1 -1
  201. package/dist/cli/index.d.ts +1 -1
  202. package/dist/cli/index.d.ts.map +1 -1
  203. package/dist/cli/index.js +1 -1
  204. package/dist/cli/index.js.map +1 -1
  205. package/dist/cli/self-update.d.ts.map +1 -1
  206. package/dist/cli/self-update.js +7 -4
  207. package/dist/cli/self-update.js.map +1 -1
  208. package/dist/cli/shell/agent-name-parser.d.ts +16 -0
  209. package/dist/cli/shell/agent-name-parser.d.ts.map +1 -0
  210. package/dist/cli/shell/agent-name-parser.js +54 -0
  211. package/dist/cli/shell/agent-name-parser.js.map +1 -0
  212. package/dist/cli/shell/commands.d.ts.map +1 -1
  213. package/dist/cli/shell/commands.js +4 -3
  214. package/dist/cli/shell/commands.js.map +1 -1
  215. package/dist/cli/shell/coordinator.d.ts +4 -1
  216. package/dist/cli/shell/coordinator.d.ts.map +1 -1
  217. package/dist/cli/shell/coordinator.js +29 -26
  218. package/dist/cli/shell/coordinator.js.map +1 -1
  219. package/dist/cli/shell/index.d.ts.map +1 -1
  220. package/dist/cli/shell/index.js +33 -35
  221. package/dist/cli/shell/index.js.map +1 -1
  222. package/dist/cli/shell/lifecycle.d.ts +13 -2
  223. package/dist/cli/shell/lifecycle.d.ts.map +1 -1
  224. package/dist/cli/shell/lifecycle.js +26 -13
  225. package/dist/cli/shell/lifecycle.js.map +1 -1
  226. package/dist/cli/shell/session-store.d.ts.map +1 -1
  227. package/dist/cli/shell/session-store.js +16 -12
  228. package/dist/cli/shell/session-store.js.map +1 -1
  229. package/dist/cli/shell/spawn.d.ts +4 -1
  230. package/dist/cli/shell/spawn.d.ts.map +1 -1
  231. package/dist/cli/shell/spawn.js +28 -10
  232. package/dist/cli/shell/spawn.js.map +1 -1
  233. package/dist/cli-entry.js +136 -12
  234. package/dist/cli-entry.js.map +1 -1
  235. package/package.json +8 -4
  236. package/scripts/patch-esm-imports.mjs +105 -105
  237. package/scripts/patch-ink-rendering.mjs +115 -115
  238. package/templates/casting/Futurama.json +9 -9
  239. package/templates/casting-history.json +4 -4
  240. package/templates/casting-policy.json +37 -37
  241. package/templates/casting-reference.md +104 -104
  242. package/templates/casting-registry.json +3 -3
  243. package/templates/ceremonies.md +41 -41
  244. package/templates/charter.md +53 -53
  245. package/templates/constraint-tracking.md +38 -38
  246. package/templates/cooperative-rate-limiting.md +229 -229
  247. package/templates/copilot-instructions.md +46 -46
  248. package/templates/history.md +10 -10
  249. package/templates/identity/now.md +9 -9
  250. package/templates/identity/wisdom.md +15 -15
  251. package/templates/issue-lifecycle.md +412 -412
  252. package/templates/keda-scaler.md +164 -164
  253. package/templates/machine-capabilities.md +74 -74
  254. package/templates/mcp-config.md +90 -90
  255. package/templates/multi-agent-format.md +28 -28
  256. package/templates/orchestration-log.md +27 -27
  257. package/templates/plugin-marketplace.md +49 -49
  258. package/templates/ralph-circuit-breaker.md +313 -313
  259. package/templates/raw-agent-output.md +37 -37
  260. package/templates/roster.md +60 -60
  261. package/templates/routing.md +39 -39
  262. package/templates/run-output.md +50 -50
  263. package/templates/scribe-charter.md +123 -119
  264. package/templates/skill.md +24 -24
  265. package/templates/skills/agent-collaboration/SKILL.md +42 -42
  266. package/templates/skills/agent-conduct/SKILL.md +24 -24
  267. package/templates/skills/architectural-proposals/SKILL.md +151 -151
  268. package/templates/skills/ci-validation-gates/SKILL.md +84 -84
  269. package/templates/skills/cli-wiring/SKILL.md +47 -47
  270. package/templates/skills/client-compatibility/SKILL.md +89 -89
  271. package/templates/skills/cross-machine-coordination/SKILL.md +434 -0
  272. package/templates/skills/cross-squad/SKILL.md +114 -114
  273. package/templates/skills/distributed-mesh/SKILL.md +287 -287
  274. package/templates/skills/distributed-mesh/mesh.json.example +30 -30
  275. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
  276. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
  277. package/templates/skills/docs-standards/SKILL.md +71 -71
  278. package/templates/skills/economy-mode/SKILL.md +114 -114
  279. package/templates/skills/error-recovery/SKILL.md +99 -0
  280. package/templates/skills/external-comms/SKILL.md +329 -329
  281. package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
  282. package/templates/skills/git-workflow/SKILL.md +204 -204
  283. package/templates/skills/github-multi-account/SKILL.md +95 -95
  284. package/templates/skills/history-hygiene/SKILL.md +36 -36
  285. package/templates/skills/humanizer/SKILL.md +105 -105
  286. package/templates/skills/init-mode/SKILL.md +102 -102
  287. package/templates/skills/iterative-retrieval/SKILL.md +165 -0
  288. package/templates/skills/model-selection/SKILL.md +117 -117
  289. package/templates/skills/nap/SKILL.md +24 -24
  290. package/templates/skills/notification-routing/SKILL.md +105 -0
  291. package/templates/skills/personal-squad/SKILL.md +57 -57
  292. package/templates/skills/pr-screenshots/SKILL.md +149 -0
  293. package/templates/skills/ralph-two-pass-scan/SKILL.md +35 -0
  294. package/templates/skills/reflect/SKILL.md +229 -0
  295. package/templates/skills/release-process/SKILL.md +131 -423
  296. package/templates/skills/reskill/SKILL.md +92 -92
  297. package/templates/skills/retro-enforcement/SKILL.md +148 -0
  298. package/templates/skills/reviewer-protocol/SKILL.md +79 -79
  299. package/templates/skills/secret-handling/SKILL.md +200 -200
  300. package/templates/skills/session-recovery/SKILL.md +155 -155
  301. package/templates/skills/squad-conventions/SKILL.md +69 -69
  302. package/templates/skills/test-discipline/SKILL.md +37 -37
  303. package/templates/skills/tiered-memory/SKILL.md +234 -0
  304. package/templates/skills/windows-compatibility/SKILL.md +98 -74
  305. package/templates/{squad.agent.md → squad.agent.md.template} +1316 -1287
  306. package/templates/workflows/squad-ci.yml +24 -24
  307. package/templates/workflows/squad-docs.yml +54 -54
  308. package/templates/workflows/squad-heartbeat.yml +0 -4
  309. package/templates/workflows/squad-insider-release.yml +61 -61
  310. package/templates/workflows/squad-issue-assign.yml +161 -161
  311. package/templates/workflows/squad-label-enforce.yml +181 -181
  312. package/templates/workflows/squad-preview.yml +55 -55
  313. package/templates/workflows/squad-promote.yml +120 -120
  314. package/templates/workflows/squad-release.yml +77 -77
  315. package/templates/workflows/squad-triage.yml +260 -260
  316. package/templates/workflows/sync-squad-labels.yml +169 -169
  317. package/dist/cli/commands/watch.d.ts +0 -18
  318. package/dist/cli/commands/watch.d.ts.map +0 -1
  319. package/dist/cli/commands/watch.js +0 -306
  320. package/dist/cli/commands/watch.js.map +0 -1
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Execute capability — spawns Copilot sessions for eligible issues.
3
+ */
4
+ import { execFile } from 'node:child_process';
5
+ import path from 'node:path';
6
+ import { RatePool } from './rate-pool.js';
7
+ /** Labels that block autonomous execution. */
8
+ const BLOCKED_LABELS = new Set([
9
+ 'status:blocked',
10
+ 'status:waiting-external',
11
+ 'status:postponed',
12
+ 'status:scheduled',
13
+ 'status:needs-action',
14
+ 'status:needs-decision',
15
+ 'status:needs-review',
16
+ 'pending-user',
17
+ 'do-not-merge',
18
+ ]);
19
+ /** Build agent command for a prompt. */
20
+ function buildAgentCommand(prompt, context) {
21
+ if (context.agentCmd) {
22
+ const parts = context.agentCmd.trim().split(/\s+/);
23
+ const cmd = parts[0];
24
+ const args = [...parts.slice(1), '--message', prompt];
25
+ return { cmd, args };
26
+ }
27
+ const args = ['copilot', '--message', prompt];
28
+ if (context.copilotFlags) {
29
+ args.push(...context.copilotFlags.trim().split(/\s+/));
30
+ }
31
+ return { cmd: 'gh', args };
32
+ }
33
+ /** Find issues eligible for autonomous execution. */
34
+ export function findExecutableIssues(roster, capabilities, issues) {
35
+ const memberLabels = new Set(roster.map(m => m.label));
36
+ return issues.filter(issue => {
37
+ const labels = issue.labels.map(l => l.name);
38
+ if (!labels.some(l => memberLabels.has(l)))
39
+ return false;
40
+ if (issue.assignees && issue.assignees.length > 0)
41
+ return false;
42
+ if (labels.some(l => BLOCKED_LABELS.has(l)))
43
+ return false;
44
+ return true;
45
+ });
46
+ }
47
+ /** Spawn agent for a single issue. */
48
+ async function executeOne(issue, context, timeoutMs) {
49
+ // Claim the issue
50
+ try {
51
+ await context.adapter.addTag(issue.number, 'status:in-progress');
52
+ }
53
+ catch { /* best-effort */ }
54
+ try {
55
+ await context.adapter.addComment(issue.number, '🤖 Ralph: starting autonomous work on this issue.');
56
+ }
57
+ catch { /* best-effort */ }
58
+ const prompt = `Work on issue #${issue.number}: ${issue.title}. Read the issue body for full details.`;
59
+ const { cmd, args } = buildAgentCommand(prompt, context);
60
+ return new Promise((resolve) => {
61
+ const _cp = execFile(cmd, args, { cwd: context.teamRoot, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
62
+ if (err) {
63
+ const execErr = err;
64
+ const msg = execErr.killed ? `Timed out` : execErr.message;
65
+ resolve({ success: false, error: msg });
66
+ }
67
+ else {
68
+ resolve({ success: true });
69
+ }
70
+ });
71
+ });
72
+ }
73
+ export class ExecuteCapability {
74
+ name = 'execute';
75
+ description = 'Spawn Copilot sessions to work on eligible issues';
76
+ configShape = 'boolean';
77
+ requires = ['gh'];
78
+ phase = 'post-execute';
79
+ async preflight(_context) {
80
+ return new Promise((resolve) => {
81
+ execFile('gh', ['--version'], (err) => {
82
+ resolve(err ? { ok: false, reason: 'gh CLI not found' } : { ok: true });
83
+ });
84
+ });
85
+ }
86
+ async execute(context) {
87
+ try {
88
+ const maxConcurrent = context.config['maxConcurrent'] ?? 1;
89
+ const timeout = (context.config['timeout'] ?? 30) * 60_000;
90
+ // Fetch open issues with squad label
91
+ const sdkItems = await context.adapter.listWorkItems({ tags: ['squad'], state: 'open', limit: 50 });
92
+ const issues = sdkItems.map(wi => ({
93
+ number: wi.id,
94
+ title: wi.title,
95
+ labels: wi.tags.map(t => ({ name: t })),
96
+ assignees: wi.assignedTo ? [{ login: wi.assignedTo }] : [],
97
+ }));
98
+ // Filter by capabilities
99
+ const { filterByCapabilities, loadCapabilities } = await import('@bradygaster/squad-sdk/ralph/capabilities');
100
+ const capabilities = await loadCapabilities(context.teamRoot);
101
+ const { handled } = filterByCapabilities(issues, capabilities);
102
+ const executable = findExecutableIssues(context.roster, capabilities, handled);
103
+ const batch = executable.slice(0, maxConcurrent);
104
+ if (batch.length === 0) {
105
+ return { success: true, summary: 'no executable issues' };
106
+ }
107
+ // Rate pool gate — respect shared API budget across instances
108
+ const poolCfg = context.config['ratePool'];
109
+ const squadDir = path.join(context.teamRoot, '.squad');
110
+ const ratePool = new RatePool(squadDir, {
111
+ maxCallsPerInterval: poolCfg?.['maxCallsPerInterval'] ?? undefined,
112
+ intervalSeconds: poolCfg?.['intervalSeconds'] ?? undefined,
113
+ poolFile: poolCfg?.['poolFile'] ?? undefined,
114
+ });
115
+ const admitted = [];
116
+ const skipped = [];
117
+ for (const issue of batch) {
118
+ if (ratePool.acquireSlot()) {
119
+ admitted.push(issue);
120
+ }
121
+ else {
122
+ skipped.push(issue.number);
123
+ }
124
+ }
125
+ if (admitted.length === 0) {
126
+ const status = ratePool.getPoolStatus();
127
+ return {
128
+ success: true,
129
+ summary: `rate pool exhausted (${status.slotsUsed}/${status.maxSlots}), ${skipped.length} skipped`,
130
+ };
131
+ }
132
+ if (skipped.length > 0) {
133
+ console.log(`[rate-pool] skipped issues due to budget: ${skipped.join(', ')}`);
134
+ }
135
+ const results = await Promise.all(admitted.map(async (issue) => {
136
+ try {
137
+ return await executeOne(issue, context, timeout);
138
+ }
139
+ finally {
140
+ ratePool.releaseSlot();
141
+ }
142
+ }));
143
+ const succeeded = results.filter(r => r.success).length;
144
+ const failed = results.length - succeeded;
145
+ return {
146
+ success: true,
147
+ summary: `${succeeded} executed, ${failed} failed`,
148
+ data: { executed: succeeded, failed },
149
+ };
150
+ }
151
+ catch (e) {
152
+ return { success: false, summary: `execute error: ${e.message}` };
153
+ }
154
+ }
155
+ }
156
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Health-check capability — pre-round watchdog.
3
+ *
4
+ * Ported from ralph-watch.ps1 `Invoke-RalphHealthCheck`.
5
+ * Runs in the `pre-scan` phase and verifies:
6
+ * 1. gh CLI authenticated
7
+ * 2. Circuit breaker state file is valid
8
+ * 3. Disk space above threshold (configurable, default 500 MB)
9
+ * 4. Git branch matches expected (optional)
10
+ *
11
+ * Config (via squad.config.ts → watch.capabilities["health-check"]):
12
+ * diskThresholdMB – minimum free disk in MB (default: 500)
13
+ * expectedBranch – warn if not on this branch (optional)
14
+ */
15
+ import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
16
+ export interface HealthCheckResult {
17
+ healed: string[];
18
+ warnings: string[];
19
+ }
20
+ export declare class HealthCheckCapability implements WatchCapability {
21
+ readonly name = "health-check";
22
+ readonly description = "Pre-round watchdog: verify auth, disk space, branch, CB state";
23
+ readonly configShape: "object";
24
+ readonly requires: string[];
25
+ readonly phase: "pre-scan";
26
+ preflight(_context: WatchContext): Promise<PreflightResult>;
27
+ execute(context: WatchContext): Promise<CapabilityResult>;
28
+ }
29
+ //# sourceMappingURL=health-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/health-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpG,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,WAAW,mEAAmE;IACvF,QAAQ,CAAC,WAAW,EAAG,QAAQ,CAAU;IACzC,QAAQ,CAAC,QAAQ,WAAU;IAC3B,QAAQ,CAAC,KAAK,EAAG,UAAU,CAAU;IAE/B,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA0EhE"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Health-check capability — pre-round watchdog.
3
+ *
4
+ * Ported from ralph-watch.ps1 `Invoke-RalphHealthCheck`.
5
+ * Runs in the `pre-scan` phase and verifies:
6
+ * 1. gh CLI authenticated
7
+ * 2. Circuit breaker state file is valid
8
+ * 3. Disk space above threshold (configurable, default 500 MB)
9
+ * 4. Git branch matches expected (optional)
10
+ *
11
+ * Config (via squad.config.ts → watch.capabilities["health-check"]):
12
+ * diskThresholdMB – minimum free disk in MB (default: 500)
13
+ * expectedBranch – warn if not on this branch (optional)
14
+ */
15
+ import { execFile } from 'node:child_process';
16
+ import { promisify } from 'node:util';
17
+ import path from 'node:path';
18
+ import fs from 'node:fs';
19
+ const execFileAsync = promisify(execFile);
20
+ export class HealthCheckCapability {
21
+ name = 'health-check';
22
+ description = 'Pre-round watchdog: verify auth, disk space, branch, CB state';
23
+ configShape = 'object';
24
+ requires = ['gh'];
25
+ phase = 'pre-scan';
26
+ async preflight(_context) {
27
+ return { ok: true };
28
+ }
29
+ async execute(context) {
30
+ const healed = [];
31
+ const warnings = [];
32
+ const config = context.config;
33
+ const diskThresholdMB = config['diskThresholdMB'] ?? 500;
34
+ const expectedBranch = config['expectedBranch'];
35
+ // 1. Verify gh auth
36
+ try {
37
+ await execFileAsync('gh', ['auth', 'status'], { timeout: 10_000 });
38
+ }
39
+ catch {
40
+ // Try extracting auth info from git remote (P3 auth fallback)
41
+ const patFromRemote = await extractPatFromRemote(context.teamRoot);
42
+ if (patFromRemote) {
43
+ healed.push('Detected PAT in git remote URL — gh auth may need refresh');
44
+ }
45
+ else {
46
+ warnings.push('gh auth: not authenticated — run "gh auth login"');
47
+ }
48
+ }
49
+ // 2. Validate circuit breaker state file
50
+ const cbPath = path.join(context.teamRoot, '.squad', 'ralph-circuit-breaker.json');
51
+ try {
52
+ if (fs.existsSync(cbPath)) {
53
+ const rawContent = fs.readFileSync(cbPath, 'utf-8');
54
+ const parsed = JSON.parse(rawContent);
55
+ // Check for nested schema (legacy)
56
+ if (!parsed.preferredModel && parsed.model_fallback) {
57
+ healed.push('CB schema: would convert nested→flat on next use');
58
+ }
59
+ // Check for empty model
60
+ if (parsed.currentModel === '' || parsed.currentModel === null) {
61
+ warnings.push('CB state has empty currentModel — circuit-breaker will auto-reset');
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ // No CB file is fine — will be created on demand
67
+ }
68
+ // 3. Disk space check
69
+ try {
70
+ const freeBytes = await getFreeDiskSpace(context.teamRoot);
71
+ const freeMB = Math.floor(freeBytes / (1024 * 1024));
72
+ if (freeMB < diskThresholdMB) {
73
+ warnings.push(`Low disk space: ${freeMB} MB free (threshold: ${diskThresholdMB} MB)`);
74
+ }
75
+ }
76
+ catch {
77
+ // Disk check failed — non-blocking
78
+ }
79
+ // 4. Branch drift check
80
+ if (expectedBranch) {
81
+ try {
82
+ const { stdout } = await execFileAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
83
+ cwd: context.teamRoot,
84
+ timeout: 5_000,
85
+ });
86
+ const current = stdout.trim();
87
+ if (current && current !== expectedBranch) {
88
+ warnings.push(`Branch drift: on "${current}" (expected "${expectedBranch}")`);
89
+ }
90
+ }
91
+ catch { /* not a git repo or other error */ }
92
+ }
93
+ const summary = healed.length > 0 || warnings.length > 0
94
+ ? `healed: ${healed.length}, warnings: ${warnings.length}`
95
+ : 'all checks passed';
96
+ return {
97
+ success: warnings.length === 0,
98
+ summary,
99
+ data: { healed, warnings },
100
+ };
101
+ }
102
+ }
103
+ /** Try extracting a PAT from git remote URL (https://<pat>@github.com/...) */
104
+ async function extractPatFromRemote(cwd) {
105
+ try {
106
+ const { stdout } = await execFileAsync('git', ['config', '--get', 'remote.origin.url'], {
107
+ cwd,
108
+ timeout: 5_000,
109
+ });
110
+ const url = stdout.trim();
111
+ // Pattern: https://<token>@github.com/...
112
+ const match = url.match(/https:\/\/([^@]+)@github\.com/);
113
+ if (match && match[1] && match[1] !== 'oauth2') {
114
+ return match[1];
115
+ }
116
+ }
117
+ catch { /* not available */ }
118
+ return null;
119
+ }
120
+ /** Get free disk space in bytes for the drive containing the given path. */
121
+ async function getFreeDiskSpace(dirPath) {
122
+ const platform = process.platform;
123
+ if (platform === 'win32') {
124
+ const drive = path.parse(path.resolve(dirPath)).root;
125
+ const { stdout } = await execFileAsync('wmic', [
126
+ 'logicaldisk', 'where', `DeviceID='${drive.replace('\\', '')}'`,
127
+ 'get', 'FreeSpace', '/value',
128
+ ], { timeout: 5_000 });
129
+ const match = stdout.match(/FreeSpace=(\d+)/);
130
+ return match ? parseInt(match[1], 10) : Infinity;
131
+ }
132
+ // Unix: use df
133
+ const { stdout } = await execFileAsync('df', ['--output=avail', '-B1', dirPath], {
134
+ timeout: 5_000,
135
+ });
136
+ const lines = stdout.trim().split('\n');
137
+ return parseInt(lines[lines.length - 1].trim(), 10) || Infinity;
138
+ }
139
+ //# sourceMappingURL=health-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/health-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Heartbeat capability — write status JSON every round.
3
+ *
4
+ * Ported from ralph-watch.ps1 `Update-Heartbeat`.
5
+ * Writes to `.squad/ralph-heartbeat.json` every round with:
6
+ * - round number, status, PID, timestamp
7
+ * - consecutive failures counter
8
+ * - duration of last round
9
+ *
10
+ * Also maintains a structured log at `.squad/ralph-watch.log` with rotation.
11
+ *
12
+ * Runs in the `housekeeping` phase.
13
+ *
14
+ * Config (via squad.config.ts → watch.capabilities["heartbeat"]):
15
+ * heartbeatPath – override heartbeat file location (default: .squad/ralph-heartbeat.json)
16
+ * logPath – override log file location (default: .squad/ralph-watch.log)
17
+ * maxLogEntries – max log lines before rotation (default: 500)
18
+ * maxLogBytes – max log file size before rotation (default: 1MB)
19
+ */
20
+ import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
21
+ export interface HeartbeatData {
22
+ lastRun: string;
23
+ lastHeartbeat: string;
24
+ round: number;
25
+ status: string;
26
+ exitCode: number;
27
+ durationSeconds: number;
28
+ consecutiveFailures: number;
29
+ pid: number;
30
+ }
31
+ export declare class HeartbeatCapability implements WatchCapability {
32
+ readonly name = "heartbeat";
33
+ readonly description = "Write heartbeat JSON and structured log every round";
34
+ readonly configShape: "object";
35
+ readonly requires: never[];
36
+ readonly phase: "housekeeping";
37
+ preflight(_context: WatchContext): Promise<PreflightResult>;
38
+ execute(context: WatchContext): Promise<CapabilityResult>;
39
+ }
40
+ /** Increment consecutive failure counter (called by the main loop on error). */
41
+ export declare function recordFailure(): void;
42
+ /** Reset consecutive failure counter (called by the main loop on success). */
43
+ export declare function recordSuccess(): void;
44
+ /** Get current consecutive failure count. */
45
+ export declare function getConsecutiveFailures(): number;
46
+ /** Mark round start time for duration tracking. */
47
+ export declare function markRoundStart(): void;
48
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpG,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAMD,qBAAa,mBAAoB,YAAW,eAAe;IACzD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,yDAAyD;IAC7E,QAAQ,CAAC,WAAW,EAAG,QAAQ,CAAU;IACzC,QAAQ,CAAC,QAAQ,UAAM;IACvB,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA2ChE;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,mDAAmD;AACnD,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Heartbeat capability — write status JSON every round.
3
+ *
4
+ * Ported from ralph-watch.ps1 `Update-Heartbeat`.
5
+ * Writes to `.squad/ralph-heartbeat.json` every round with:
6
+ * - round number, status, PID, timestamp
7
+ * - consecutive failures counter
8
+ * - duration of last round
9
+ *
10
+ * Also maintains a structured log at `.squad/ralph-watch.log` with rotation.
11
+ *
12
+ * Runs in the `housekeeping` phase.
13
+ *
14
+ * Config (via squad.config.ts → watch.capabilities["heartbeat"]):
15
+ * heartbeatPath – override heartbeat file location (default: .squad/ralph-heartbeat.json)
16
+ * logPath – override log file location (default: .squad/ralph-watch.log)
17
+ * maxLogEntries – max log lines before rotation (default: 500)
18
+ * maxLogBytes – max log file size before rotation (default: 1MB)
19
+ */
20
+ import path from 'node:path';
21
+ import fs from 'node:fs';
22
+ // Module-level state tracked across rounds
23
+ let consecutiveFailures = 0;
24
+ let lastRoundStart = Date.now();
25
+ export class HeartbeatCapability {
26
+ name = 'heartbeat';
27
+ description = 'Write heartbeat JSON and structured log every round';
28
+ configShape = 'object';
29
+ requires = [];
30
+ phase = 'housekeeping';
31
+ async preflight(_context) {
32
+ return { ok: true };
33
+ }
34
+ async execute(context) {
35
+ const config = context.config;
36
+ const squadDir = path.join(context.teamRoot, '.squad');
37
+ const heartbeatPath = config['heartbeatPath'] ?? path.join(squadDir, 'ralph-heartbeat.json');
38
+ const logPath = config['logPath'] ?? path.join(squadDir, 'ralph-watch.log');
39
+ const maxLogEntries = config['maxLogEntries'] ?? 500;
40
+ const maxLogBytes = config['maxLogBytes'] ?? 1_048_576; // 1 MB
41
+ const now = new Date();
42
+ const durationSeconds = Math.round((Date.now() - lastRoundStart) / 1000 * 100) / 100;
43
+ lastRoundStart = Date.now();
44
+ // Write heartbeat
45
+ const heartbeat = {
46
+ lastRun: now.toISOString(),
47
+ lastHeartbeat: now.toISOString(),
48
+ round: context.round,
49
+ status: 'idle',
50
+ exitCode: 0,
51
+ durationSeconds,
52
+ consecutiveFailures,
53
+ pid: process.pid,
54
+ };
55
+ try {
56
+ ensureDir(path.dirname(heartbeatPath));
57
+ fs.writeFileSync(heartbeatPath, JSON.stringify(heartbeat, null, 2), 'utf-8');
58
+ }
59
+ catch { /* best-effort */ }
60
+ // Append structured log entry
61
+ const logEntry = `${now.toISOString()} | Round=${context.round} | Duration=${durationSeconds}s | Failures=${consecutiveFailures} | Status=idle`;
62
+ try {
63
+ ensureDir(path.dirname(logPath));
64
+ fs.appendFileSync(logPath, logEntry + '\n', 'utf-8');
65
+ rotateLog(logPath, maxLogEntries, maxLogBytes);
66
+ }
67
+ catch { /* best-effort */ }
68
+ return {
69
+ success: true,
70
+ summary: `heartbeat written (round ${context.round})`,
71
+ data: { heartbeatPath, durationSeconds },
72
+ };
73
+ }
74
+ }
75
+ /** Increment consecutive failure counter (called by the main loop on error). */
76
+ export function recordFailure() {
77
+ consecutiveFailures++;
78
+ }
79
+ /** Reset consecutive failure counter (called by the main loop on success). */
80
+ export function recordSuccess() {
81
+ consecutiveFailures = 0;
82
+ }
83
+ /** Get current consecutive failure count. */
84
+ export function getConsecutiveFailures() {
85
+ return consecutiveFailures;
86
+ }
87
+ /** Mark round start time for duration tracking. */
88
+ export function markRoundStart() {
89
+ lastRoundStart = Date.now();
90
+ }
91
+ function ensureDir(dir) {
92
+ if (!fs.existsSync(dir)) {
93
+ fs.mkdirSync(dir, { recursive: true });
94
+ }
95
+ }
96
+ function rotateLog(logPath, maxEntries, maxBytes) {
97
+ try {
98
+ const stat = fs.statSync(logPath);
99
+ let needsRotation = stat.size > maxBytes;
100
+ if (!needsRotation) {
101
+ const content = fs.readFileSync(logPath, 'utf-8');
102
+ const lines = content.split('\n').filter(Boolean);
103
+ needsRotation = lines.length > maxEntries;
104
+ }
105
+ if (needsRotation) {
106
+ const content = fs.readFileSync(logPath, 'utf-8');
107
+ const lines = content.split('\n').filter(Boolean);
108
+ const kept = lines.slice(-Math.max(maxEntries - 1, 1));
109
+ const header = `# Ralph Watch Log — Rotated ${new Date().toISOString()} (kept last ${kept.length} entries)`;
110
+ fs.writeFileSync(logPath, [header, ...kept].join('\n') + '\n', 'utf-8');
111
+ }
112
+ }
113
+ catch { /* best-effort */ }
114
+ }
115
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAczB,2CAA2C;AAC3C,IAAI,mBAAmB,GAAG,CAAC,CAAC;AAC5B,IAAI,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAEhC,MAAM,OAAO,mBAAmB;IACrB,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,qDAAqD,CAAC;IACpE,WAAW,GAAG,QAAiB,CAAC;IAChC,QAAQ,GAAG,EAAE,CAAC;IACd,KAAK,GAAG,cAAuB,CAAC;IAEzC,KAAK,CAAC,SAAS,CAAC,QAAsB;QACpC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAqB;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAiC,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,aAAa,GAAI,MAAM,CAAC,eAAe,CAAY,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;QACzG,MAAM,OAAO,GAAI,MAAM,CAAC,SAAS,CAAY,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QACxF,MAAM,aAAa,GAAI,MAAM,CAAC,eAAe,CAAY,IAAI,GAAG,CAAC;QACjE,MAAM,WAAW,GAAI,MAAM,CAAC,aAAa,CAAY,IAAI,SAAS,CAAC,CAAC,OAAO;QAE3E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACrF,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE5B,kBAAkB;QAClB,MAAM,SAAS,GAAkB;YAC/B,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE;YAC1B,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE;YAChC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,CAAC;YACX,eAAe;YACf,mBAAmB;YACnB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC;QAEF,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;YACvC,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/E,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE7B,8BAA8B;QAC9B,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,YAAY,OAAO,CAAC,KAAK,eAAe,eAAe,gBAAgB,mBAAmB,gBAAgB,CAAC;QAChJ,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACjC,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;YACrD,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE7B,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,4BAA4B,OAAO,CAAC,KAAK,GAAG;YACrD,IAAI,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE;SACzC,CAAC;IACJ,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa;IAC3B,mBAAmB,EAAE,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa;IAC3B,mBAAmB,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,sBAAsB;IACpC,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,cAAc;IAC5B,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,OAAe,EAAE,UAAkB,EAAE,QAAgB;IACtE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,aAAa,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QAEzC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClD,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;QAC5C,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,+BAA+B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,IAAI,CAAC,MAAM,WAAW,CAAC;YAC5G,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Capability barrel — registers all built-in capabilities.
3
+ */
4
+ import { CapabilityRegistry } from '../registry.js';
5
+ export { RatePool } from './rate-pool.js';
6
+ export type { RatePoolConfig, PoolStatus } from './rate-pool.js';
7
+ /** Create a registry pre-loaded with all built-in capabilities. */
8
+ export declare function createDefaultRegistry(): CapabilityRegistry;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAkBpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjE,mEAAmE;AACnE,wBAAgB,qBAAqB,IAAI,kBAAkB,CAkB1D"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Capability barrel — registers all built-in capabilities.
3
+ */
4
+ import { CapabilityRegistry } from '../registry.js';
5
+ import { SelfPullCapability } from './self-pull.js';
6
+ import { ExecuteCapability } from './execute.js';
7
+ import { BoardCapability } from './board.js';
8
+ import { MonitorTeamsCapability } from './monitor-teams.js';
9
+ import { MonitorEmailCapability } from './monitor-email.js';
10
+ import { TwoPassCapability } from './two-pass.js';
11
+ import { WaveDispatchCapability } from './wave-dispatch.js';
12
+ import { RetroCapability } from './retro.js';
13
+ import { DecisionHygieneCapability } from './decision-hygiene.js';
14
+ // ── Watch parity capabilities (ported from ralph-watch.ps1, #743) ──
15
+ import { HealthCheckCapability } from './health-check.js';
16
+ import { StaleReclaimCapability } from './stale-reclaim.js';
17
+ import { HeartbeatCapability } from './heartbeat.js';
18
+ import { WebhookAlertCapability } from './webhook-alerts.js';
19
+ // Re-export rate pool for direct consumption (utility, not a phase capability)
20
+ export { RatePool } from './rate-pool.js';
21
+ /** Create a registry pre-loaded with all built-in capabilities. */
22
+ export function createDefaultRegistry() {
23
+ const registry = new CapabilityRegistry();
24
+ registry.register(new SelfPullCapability());
25
+ registry.register(new ExecuteCapability());
26
+ registry.register(new BoardCapability());
27
+ registry.register(new MonitorTeamsCapability());
28
+ registry.register(new MonitorEmailCapability());
29
+ registry.register(new TwoPassCapability());
30
+ registry.register(new WaveDispatchCapability());
31
+ registry.register(new RetroCapability());
32
+ registry.register(new DecisionHygieneCapability());
33
+ // Watch parity capabilities (#743)
34
+ registry.register(new HealthCheckCapability());
35
+ registry.register(new StaleReclaimCapability());
36
+ registry.register(new HeartbeatCapability());
37
+ registry.register(new WebhookAlertCapability());
38
+ return registry;
39
+ }
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,sEAAsE;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,mEAAmE;AACnE,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAyB,EAAE,CAAC,CAAC;IAEnD,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Lockfile utility — per-repo lock with PID, timestamp, and stale detection.
3
+ *
4
+ * Ported from ralph-watch.ps1 lockfile logic.
5
+ * Written BEFORE a round (status=running) and AFTER (status=idle/error).
6
+ * External tools (e.g., squad-monitor) can read this file to know if
7
+ * a watch process is active.
8
+ *
9
+ * This is a utility module — not a WatchCapability.
10
+ */
11
+ export interface LockfileData {
12
+ pid: number;
13
+ status: 'running' | 'idle' | 'error';
14
+ round: number;
15
+ lastRun: string;
16
+ exitCode: number;
17
+ consecutiveFailures: number;
18
+ started: string;
19
+ directory: string;
20
+ }
21
+ /**
22
+ * Acquire a lockfile for this watch process.
23
+ * Returns false if another non-stale process holds the lock.
24
+ */
25
+ export declare function acquireLock(teamRoot: string): boolean;
26
+ /** Update the lockfile with current round state. */
27
+ export declare function updateLock(teamRoot: string, status: 'running' | 'idle' | 'error', round: number, exitCode?: number, consecutiveFailures?: number): void;
28
+ /** Release the lockfile on shutdown. */
29
+ export declare function releaseLock(teamRoot: string): void;
30
+ //# sourceMappingURL=lockfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAiCrD;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACpC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAU,EACpB,mBAAmB,GAAE,MAAU,GAC9B,IAAI,CAiBN;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAUlD"}