@pennyfarthing/core 10.0.1 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/package.json +13 -3
  2. package/pennyfarthing-dist/agents/README.md +348 -0
  3. package/pennyfarthing-dist/agents/architect.md +180 -0
  4. package/pennyfarthing-dist/agents/dev.md +169 -0
  5. package/pennyfarthing-dist/agents/devops.md +203 -0
  6. package/pennyfarthing-dist/agents/handoff.md +235 -0
  7. package/pennyfarthing-dist/agents/orchestrator.md +182 -0
  8. package/pennyfarthing-dist/agents/pm.md +152 -0
  9. package/pennyfarthing-dist/agents/reviewer-preflight.md +129 -0
  10. package/pennyfarthing-dist/agents/reviewer.md +197 -0
  11. package/pennyfarthing-dist/agents/sm-file-summary.md +79 -0
  12. package/pennyfarthing-dist/agents/sm-finish.md +82 -0
  13. package/pennyfarthing-dist/agents/sm-handoff.md +129 -0
  14. package/pennyfarthing-dist/agents/sm-setup.md +251 -0
  15. package/pennyfarthing-dist/agents/sm.md +298 -0
  16. package/pennyfarthing-dist/agents/tea.md +161 -0
  17. package/pennyfarthing-dist/agents/tech-writer.md +226 -0
  18. package/pennyfarthing-dist/agents/testing-runner.md +184 -0
  19. package/pennyfarthing-dist/agents/ux-designer.md +236 -0
  20. package/pennyfarthing-dist/agents/workflow-status-check.md +96 -0
  21. package/pennyfarthing-dist/commands/architect.md +9 -0
  22. package/pennyfarthing-dist/commands/benchmark-control.md +69 -0
  23. package/pennyfarthing-dist/commands/benchmark.md +485 -0
  24. package/pennyfarthing-dist/commands/brainstorming.md +91 -0
  25. package/pennyfarthing-dist/commands/check.md +156 -0
  26. package/pennyfarthing-dist/commands/chore.md +218 -0
  27. package/pennyfarthing-dist/commands/close-epic.md +139 -0
  28. package/pennyfarthing-dist/commands/continue-session.md +218 -0
  29. package/pennyfarthing-dist/commands/create-branches-from-story.md +358 -0
  30. package/pennyfarthing-dist/commands/create-theme.md +29 -0
  31. package/pennyfarthing-dist/commands/dev.md +9 -0
  32. package/pennyfarthing-dist/commands/devops.md +9 -0
  33. package/pennyfarthing-dist/commands/fix-blocker.md +22 -0
  34. package/pennyfarthing-dist/commands/git-cleanup.md +57 -0
  35. package/pennyfarthing-dist/commands/health-check.md +143 -0
  36. package/pennyfarthing-dist/commands/help.md +264 -0
  37. package/pennyfarthing-dist/commands/job-fair.md +102 -0
  38. package/pennyfarthing-dist/commands/list-themes.md +21 -0
  39. package/pennyfarthing-dist/commands/new-work.md +23 -0
  40. package/pennyfarthing-dist/commands/orchestrator.md +9 -0
  41. package/pennyfarthing-dist/commands/parallel-work.md +73 -0
  42. package/pennyfarthing-dist/commands/party-mode.md +77 -0
  43. package/pennyfarthing-dist/commands/patch.md +210 -0
  44. package/pennyfarthing-dist/commands/permissions.md +193 -0
  45. package/pennyfarthing-dist/commands/pm.md +9 -0
  46. package/pennyfarthing-dist/commands/prime.md +136 -0
  47. package/pennyfarthing-dist/commands/release.md +74 -0
  48. package/pennyfarthing-dist/commands/repo-status.md +49 -0
  49. package/pennyfarthing-dist/commands/retro.md +200 -0
  50. package/pennyfarthing-dist/commands/reviewer.md +9 -0
  51. package/pennyfarthing-dist/commands/run-ci.md +116 -0
  52. package/pennyfarthing-dist/commands/set-theme.md +56 -0
  53. package/pennyfarthing-dist/commands/setup.md +65 -0
  54. package/pennyfarthing-dist/commands/show-theme.md +21 -0
  55. package/pennyfarthing-dist/commands/sm.md +9 -0
  56. package/pennyfarthing-dist/commands/solo.md +447 -0
  57. package/pennyfarthing-dist/commands/sprint-planning.md +109 -0
  58. package/pennyfarthing-dist/commands/sprint.md +142 -0
  59. package/pennyfarthing-dist/commands/standalone.md +194 -0
  60. package/pennyfarthing-dist/commands/start-epic.md +168 -0
  61. package/pennyfarthing-dist/commands/sync-epic-to-jira.md +184 -0
  62. package/pennyfarthing-dist/commands/sync-work-with-sprint.md +373 -0
  63. package/pennyfarthing-dist/commands/tea.md +9 -0
  64. package/pennyfarthing-dist/commands/tech-writer.md +9 -0
  65. package/pennyfarthing-dist/commands/theme-maker.md +676 -0
  66. package/pennyfarthing-dist/commands/update-domain-docs.md +83 -0
  67. package/pennyfarthing-dist/commands/ux-designer.md +9 -0
  68. package/pennyfarthing-dist/commands/work.md +25 -0
  69. package/pennyfarthing-dist/commands/workflow.md +21 -0
  70. package/pennyfarthing-dist/guides/agent-behavior.md +92 -0
  71. package/pennyfarthing-dist/guides/agent-coordination.md +475 -0
  72. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +432 -0
  73. package/pennyfarthing-dist/guides/agent-template-strategic.md +148 -0
  74. package/pennyfarthing-dist/guides/agent-template-tactical.md +162 -0
  75. package/pennyfarthing-dist/guides/hooks.md +230 -0
  76. package/pennyfarthing-dist/guides/measurement-framework.md +210 -0
  77. package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +766 -0
  78. package/pennyfarthing-dist/guides/patterns/fan-out-fan-in-pattern.md +574 -0
  79. package/pennyfarthing-dist/guides/patterns/helper-delegation-pattern.md +488 -0
  80. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +402 -0
  81. package/pennyfarthing-dist/guides/permission-protocol.md +188 -0
  82. package/pennyfarthing-dist/guides/persona-loading.md +46 -0
  83. package/pennyfarthing-dist/guides/prompt-patterns.md +338 -0
  84. package/pennyfarthing-dist/guides/scale-levels.md +114 -0
  85. package/pennyfarthing-dist/guides/session-artifacts.md +193 -0
  86. package/pennyfarthing-dist/guides/session-schema.md +346 -0
  87. package/pennyfarthing-dist/guides/skill-schema.md +412 -0
  88. package/pennyfarthing-dist/guides/workflow-schema.md +257 -0
  89. package/pennyfarthing-dist/guides/workflow-step-schema.md +512 -0
  90. package/pennyfarthing-dist/guides/worktree-mode.md +113 -0
  91. package/pennyfarthing-dist/guides/xml-tags.md +627 -0
  92. package/pennyfarthing-dist/output-styles/teaching.md +33 -0
  93. package/pennyfarthing-dist/output-styles/terse.md +20 -0
  94. package/pennyfarthing-dist/output-styles/verbose.md +28 -0
  95. package/pennyfarthing-dist/personas/themes/a-team.yaml +331 -0
  96. package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +324 -0
  97. package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +282 -0
  98. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +289 -0
  99. package/pennyfarthing-dist/personas/themes/catch-22.yaml +304 -0
  100. package/pennyfarthing-dist/personas/themes/control.yaml +201 -0
  101. package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +315 -0
  102. package/pennyfarthing-dist/personas/themes/discworld.yaml +334 -0
  103. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +284 -0
  104. package/pennyfarthing-dist/personas/themes/dune.yaml +301 -0
  105. package/pennyfarthing-dist/personas/themes/firefly.yaml +320 -0
  106. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +284 -0
  107. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +316 -0
  108. package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +323 -0
  109. package/pennyfarthing-dist/personas/themes/lord-of-the-rings.yaml +326 -0
  110. package/pennyfarthing-dist/personas/themes/mad-max.yaml +349 -0
  111. package/pennyfarthing-dist/personas/themes/mash.yaml +329 -0
  112. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +344 -0
  113. package/pennyfarthing-dist/personas/themes/sandman.yaml +282 -0
  114. package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +358 -0
  115. package/pennyfarthing-dist/personas/themes/star-wars.yaml +297 -0
  116. package/pennyfarthing-dist/personas/themes/the-expanse.yaml +337 -0
  117. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +342 -0
  118. package/pennyfarthing-dist/personas/themes/watchmen.yaml +285 -0
  119. package/pennyfarthing-dist/personas/themes/west-wing.yaml +285 -0
  120. package/pennyfarthing-dist/personas/themes/x-files.yaml +296 -0
  121. package/pennyfarthing-dist/scripts/README.md +87 -0
  122. package/pennyfarthing-dist/scripts/core/README.md +25 -0
  123. package/pennyfarthing-dist/scripts/core/agent-session.sh +390 -0
  124. package/pennyfarthing-dist/scripts/core/check-context.sh +194 -0
  125. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +112 -0
  126. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +90 -0
  127. package/pennyfarthing-dist/scripts/core/prime.sh +30 -0
  128. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +21 -0
  129. package/pennyfarthing-dist/scripts/git/README.md +25 -0
  130. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +267 -0
  131. package/pennyfarthing-dist/scripts/git/git-status-all.sh +152 -0
  132. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +79 -0
  133. package/pennyfarthing-dist/scripts/git/release.sh +246 -0
  134. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +497 -0
  135. package/pennyfarthing-dist/scripts/health/drift-detection.sh +156 -0
  136. package/pennyfarthing-dist/scripts/hooks/README.md +32 -0
  137. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  138. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +106 -0
  139. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +95 -0
  140. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +65 -0
  141. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +35 -0
  142. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +150 -0
  143. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +190 -0
  144. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +71 -0
  145. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +42 -0
  146. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +20 -0
  147. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +499 -0
  148. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +30 -0
  149. package/pennyfarthing-dist/scripts/hooks/session-start.sh +97 -0
  150. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +65 -0
  151. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +78 -0
  152. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +94 -0
  153. package/pennyfarthing-dist/scripts/jira/README.md +36 -0
  154. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +95 -0
  155. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +91 -0
  156. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +22 -0
  157. package/pennyfarthing-dist/scripts/jira/jira-lib.sh +464 -0
  158. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +260 -0
  159. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +18 -0
  160. package/pennyfarthing-dist/scripts/jira/jira-sync.sh +16 -0
  161. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +16 -0
  162. package/pennyfarthing-dist/scripts/jira/sync-epic-to-jira.sh +16 -0
  163. package/pennyfarthing-dist/scripts/lib/README.md +29 -0
  164. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +177 -0
  165. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +136 -0
  166. package/pennyfarthing-dist/scripts/lib/common.sh +212 -0
  167. package/pennyfarthing-dist/scripts/lib/file-lock.sh +269 -0
  168. package/pennyfarthing-dist/scripts/lib/find-root.sh +58 -0
  169. package/pennyfarthing-dist/scripts/lib/logging.sh +186 -0
  170. package/pennyfarthing-dist/scripts/lib/retry.sh +76 -0
  171. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +102 -0
  172. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +91 -0
  173. package/pennyfarthing-dist/scripts/misc/README.md +44 -0
  174. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +13 -0
  175. package/pennyfarthing-dist/scripts/misc/add_short_names.py +226 -0
  176. package/pennyfarthing-dist/scripts/misc/backlog.sh +77 -0
  177. package/pennyfarthing-dist/scripts/misc/check-status.sh +247 -0
  178. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +231 -0
  179. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +107 -0
  180. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +74 -0
  181. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +10 -0
  182. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +319 -0
  183. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +141 -0
  184. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +778 -0
  185. package/pennyfarthing-dist/scripts/misc/run-ci.sh +212 -0
  186. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +7 -0
  187. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +319 -0
  188. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +193 -0
  189. package/pennyfarthing-dist/scripts/misc/statusline.sh +257 -0
  190. package/pennyfarthing-dist/scripts/misc/uninstall.sh +275 -0
  191. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +160 -0
  192. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +417 -0
  193. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +54 -0
  194. package/pennyfarthing-dist/scripts/sprint/README.md +29 -0
  195. package/pennyfarthing-dist/scripts/sprint/archive-story.sh +133 -0
  196. package/pennyfarthing-dist/scripts/sprint/available-stories.sh +91 -0
  197. package/pennyfarthing-dist/scripts/sprint/check-story.sh +158 -0
  198. package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +52 -0
  199. package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +63 -0
  200. package/pennyfarthing-dist/scripts/sprint/list-future.sh +145 -0
  201. package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +110 -0
  202. package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +148 -0
  203. package/pennyfarthing-dist/scripts/sprint/sprint-common.sh +415 -0
  204. package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +33 -0
  205. package/pennyfarthing-dist/scripts/sprint/sprint-metrics.sh +230 -0
  206. package/pennyfarthing-dist/scripts/sprint/sprint-status.sh +134 -0
  207. package/pennyfarthing-dist/scripts/sprint/validate-sprint-yaml.sh +139 -0
  208. package/pennyfarthing-dist/scripts/story/README.md +23 -0
  209. package/pennyfarthing-dist/scripts/story/create-story.sh +19 -0
  210. package/pennyfarthing-dist/scripts/story/size-story.sh +18 -0
  211. package/pennyfarthing-dist/scripts/story/story-template.sh +18 -0
  212. package/pennyfarthing-dist/scripts/test/README.md +23 -0
  213. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +59 -0
  214. package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +220 -0
  215. package/pennyfarthing-dist/scripts/test/swebench-judge.py +374 -0
  216. package/pennyfarthing-dist/scripts/test/test-cache.sh +165 -0
  217. package/pennyfarthing-dist/scripts/test/test-setup.sh +337 -0
  218. package/pennyfarthing-dist/scripts/tests/check.test.sh +582 -0
  219. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +515 -0
  220. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +599 -0
  221. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +332 -0
  222. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +573 -0
  223. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +859 -0
  224. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +662 -0
  225. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +589 -0
  226. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +106 -0
  227. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +597 -0
  228. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +514 -0
  229. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +517 -0
  230. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +331 -0
  231. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +647 -0
  232. package/pennyfarthing-dist/scripts/theme/README.md +22 -0
  233. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +13 -0
  234. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +402 -0
  235. package/pennyfarthing-dist/scripts/theme/list-themes.sh +30 -0
  236. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +97 -0
  237. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +576 -0
  238. package/pennyfarthing-dist/scripts/workflow/README.md +28 -0
  239. package/pennyfarthing-dist/scripts/workflow/check.py +502 -0
  240. package/pennyfarthing-dist/scripts/workflow/check.sh +24 -0
  241. package/pennyfarthing-dist/scripts/workflow/complete-step.py +304 -0
  242. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +154 -0
  243. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +222 -0
  244. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +61 -0
  245. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +13 -0
  246. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +124 -0
  247. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +34 -0
  248. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +157 -0
  249. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +132 -0
  250. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +250 -0
  251. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +161 -0
  252. package/pennyfarthing-dist/skills/agentic-patterns/SKILL.md +246 -0
  253. package/pennyfarthing-dist/skills/changelog/SKILL.md +385 -0
  254. package/pennyfarthing-dist/skills/code-review/SKILL.md +172 -0
  255. package/pennyfarthing-dist/skills/context-engineering/SKILL.md +277 -0
  256. package/pennyfarthing-dist/skills/cyclist/SKILL.md +88 -0
  257. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +461 -0
  258. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +261 -0
  259. package/pennyfarthing-dist/skills/jira/SKILL.md +508 -0
  260. package/pennyfarthing-dist/skills/judge/SKILL.md +644 -0
  261. package/pennyfarthing-dist/skills/just/SKILL.md +414 -0
  262. package/pennyfarthing-dist/skills/mermaid/SKILL.md +256 -0
  263. package/pennyfarthing-dist/skills/otel/skill.md +227 -0
  264. package/pennyfarthing-dist/skills/permissions/skill.md +157 -0
  265. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +187 -0
  266. package/pennyfarthing-dist/skills/skill-registry.schema.json +107 -0
  267. package/pennyfarthing-dist/skills/skill-registry.yaml +393 -0
  268. package/pennyfarthing-dist/skills/sprint/scripts/archive-story.sh +101 -0
  269. package/pennyfarthing-dist/skills/sprint/scripts/available-stories.sh +97 -0
  270. package/pennyfarthing-dist/skills/sprint/scripts/check-story.sh +164 -0
  271. package/pennyfarthing-dist/skills/sprint/scripts/create-jira-epic.sh +101 -0
  272. package/pennyfarthing-dist/skills/sprint/scripts/new-sprint.sh +116 -0
  273. package/pennyfarthing-dist/skills/sprint/scripts/promote-epic.sh +164 -0
  274. package/pennyfarthing-dist/skills/sprint/scripts/sprint-info.sh +39 -0
  275. package/pennyfarthing-dist/skills/sprint/scripts/sprint-status.sh +147 -0
  276. package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +93 -0
  277. package/pennyfarthing-dist/skills/sprint/skill.md +465 -0
  278. package/pennyfarthing-dist/skills/story/scripts/create-story.sh +159 -0
  279. package/pennyfarthing-dist/skills/story/scripts/size-story.sh +198 -0
  280. package/pennyfarthing-dist/skills/story/scripts/story-template.sh +162 -0
  281. package/pennyfarthing-dist/skills/story/skill.md +219 -0
  282. package/pennyfarthing-dist/skills/systematic-debugging/SKILL.md +446 -0
  283. package/pennyfarthing-dist/skills/testing/SKILL.md +121 -0
  284. package/pennyfarthing-dist/skills/testing/references/troubleshooting.md +124 -0
  285. package/pennyfarthing-dist/skills/theme/skill.md +141 -0
  286. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +178 -0
  287. package/pennyfarthing-dist/skills/workflow/scripts/list-workflows.sh +91 -0
  288. package/pennyfarthing-dist/skills/workflow/scripts/resume-workflow.sh +163 -0
  289. package/pennyfarthing-dist/skills/workflow/scripts/show-workflow.sh +138 -0
  290. package/pennyfarthing-dist/skills/workflow/scripts/start-workflow.sh +273 -0
  291. package/pennyfarthing-dist/skills/workflow/scripts/workflow-status.sh +167 -0
  292. package/pennyfarthing-dist/skills/workflow/skill.md +345 -0
  293. package/pennyfarthing-dist/skills/yq/SKILL.md +272 -0
  294. package/pennyfarthing-dist/templates/LEADERBOARD.schema.yaml +187 -0
  295. package/pennyfarthing-dist/templates/LEADERBOARD.template.md +59 -0
  296. package/pennyfarthing-dist/templates/agent-scopes.yaml.template +276 -0
  297. package/pennyfarthing-dist/templates/pennyfarthing-settings.yaml.template +61 -0
  298. package/pennyfarthing-dist/templates/persona-config.yaml.template +22 -0
  299. package/pennyfarthing-dist/templates/preferences.yaml.template +15 -0
  300. package/pennyfarthing-dist/templates/settings.local.json.template +130 -0
  301. package/pennyfarthing-dist/templates/setup-env.sh.template +18 -0
  302. package/pennyfarthing-dist/templates/shared-context.md.template +70 -0
  303. package/pennyfarthing-dist/templates/sidecar/decisions.md.template +40 -0
  304. package/pennyfarthing-dist/templates/sidecar/gotchas.md.template +37 -0
  305. package/pennyfarthing-dist/templates/sidecar/patterns.md.template +34 -0
  306. package/pennyfarthing-dist/workflows/agent-docs.yaml +70 -0
  307. package/pennyfarthing-dist/workflows/architecture/steps/step-01-initialize.md +113 -0
  308. package/pennyfarthing-dist/workflows/architecture/steps/step-01b-continue.md +105 -0
  309. package/pennyfarthing-dist/workflows/architecture/steps/step-02-context.md +127 -0
  310. package/pennyfarthing-dist/workflows/architecture/steps/step-03-patterns.md +145 -0
  311. package/pennyfarthing-dist/workflows/architecture/steps/step-04-components.md +150 -0
  312. package/pennyfarthing-dist/workflows/architecture/steps/step-05-interfaces.md +145 -0
  313. package/pennyfarthing-dist/workflows/architecture/steps/step-06-risks.md +154 -0
  314. package/pennyfarthing-dist/workflows/architecture/steps/step-07-document.md +172 -0
  315. package/pennyfarthing-dist/workflows/architecture/templates/architecture-decision.md +102 -0
  316. package/pennyfarthing-dist/workflows/architecture.yaml +65 -0
  317. package/pennyfarthing-dist/workflows/bdd.yaml +60 -0
  318. package/pennyfarthing-dist/workflows/brainstorming/brain-methods.csv +62 -0
  319. package/pennyfarthing-dist/workflows/brainstorming/checklist.md +44 -0
  320. package/pennyfarthing-dist/workflows/brainstorming/instructions.md +736 -0
  321. package/pennyfarthing-dist/workflows/brainstorming/workflow.yaml +49 -0
  322. package/pennyfarthing-dist/workflows/code-review/checklist.md +23 -0
  323. package/pennyfarthing-dist/workflows/code-review/instructions.md +234 -0
  324. package/pennyfarthing-dist/workflows/code-review/workflow.yaml +51 -0
  325. package/pennyfarthing-dist/workflows/dev-story/checklist.md +80 -0
  326. package/pennyfarthing-dist/workflows/dev-story/instructions.xml +410 -0
  327. package/pennyfarthing-dist/workflows/dev-story/workflow.yaml +50 -0
  328. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-01-validate-prerequisites.md +281 -0
  329. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-02-design-epics.md +256 -0
  330. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-03-create-stories.md +298 -0
  331. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-04-final-validation.md +177 -0
  332. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +145 -0
  333. package/pennyfarthing-dist/workflows/epics-and-stories/templates/epics-template.md +57 -0
  334. package/pennyfarthing-dist/workflows/epics-and-stories/workflow.yaml +28 -0
  335. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +103 -0
  336. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-02-categorize.md +147 -0
  337. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-03-execute.md +215 -0
  338. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +97 -0
  339. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +78 -0
  340. package/pennyfarthing-dist/workflows/git-cleanup.yaml +59 -0
  341. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-01-document-discovery.md +211 -0
  342. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-02-prd-analysis.md +199 -0
  343. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-03-epic-coverage-validation.md +202 -0
  344. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-04-ux-alignment.md +162 -0
  345. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-05-epic-quality-review.md +280 -0
  346. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-06-final-assessment.md +158 -0
  347. package/pennyfarthing-dist/workflows/implementation-readiness/templates/readiness-report-template.md +4 -0
  348. package/pennyfarthing-dist/workflows/implementation-readiness/workflow.yaml +40 -0
  349. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-01-connect.md +257 -0
  350. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-02-explore.md +107 -0
  351. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-03-fix.md +127 -0
  352. package/pennyfarthing-dist/workflows/interactive-debug/steps/step-04-commit.md +122 -0
  353. package/pennyfarthing-dist/workflows/interactive-debug/workflow.yaml +51 -0
  354. package/pennyfarthing-dist/workflows/patch.yaml +67 -0
  355. package/pennyfarthing-dist/workflows/prd/data/domain-complexity.csv +13 -0
  356. package/pennyfarthing-dist/workflows/prd/data/prd-purpose.md +197 -0
  357. package/pennyfarthing-dist/workflows/prd/data/project-types.csv +11 -0
  358. package/pennyfarthing-dist/workflows/prd/steps-c/step-01-init.md +197 -0
  359. package/pennyfarthing-dist/workflows/prd/steps-c/step-01b-continue.md +159 -0
  360. package/pennyfarthing-dist/workflows/prd/steps-c/step-02-discovery.md +230 -0
  361. package/pennyfarthing-dist/workflows/prd/steps-c/step-03-success.md +232 -0
  362. package/pennyfarthing-dist/workflows/prd/steps-c/step-04-journeys.md +219 -0
  363. package/pennyfarthing-dist/workflows/prd/steps-c/step-05-domain.md +213 -0
  364. package/pennyfarthing-dist/workflows/prd/steps-c/step-06-innovation.md +232 -0
  365. package/pennyfarthing-dist/workflows/prd/steps-c/step-07-project-type.md +243 -0
  366. package/pennyfarthing-dist/workflows/prd/steps-c/step-08-scoping.md +234 -0
  367. package/pennyfarthing-dist/workflows/prd/steps-c/step-09-functional.md +237 -0
  368. package/pennyfarthing-dist/workflows/prd/steps-c/step-10-nonfunctional.md +248 -0
  369. package/pennyfarthing-dist/workflows/prd/steps-c/step-11-polish.md +223 -0
  370. package/pennyfarthing-dist/workflows/prd/steps-c/step-12-complete.md +186 -0
  371. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01-discovery.md +253 -0
  372. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01b-legacy-conversion.md +214 -0
  373. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-02-review.md +255 -0
  374. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-03-edit.md +259 -0
  375. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-04-complete.md +174 -0
  376. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-01-discovery.md +224 -0
  377. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02-format-detection.md +197 -0
  378. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02b-parity-check.md +215 -0
  379. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-03-density-validation.md +180 -0
  380. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +220 -0
  381. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-05-measurability-validation.md +234 -0
  382. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-06-traceability-validation.md +223 -0
  383. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +211 -0
  384. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +249 -0
  385. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-09-project-type-validation.md +269 -0
  386. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-10-smart-validation.md +215 -0
  387. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +270 -0
  388. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-12-completeness-validation.md +248 -0
  389. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-13-report-complete.md +238 -0
  390. package/pennyfarthing-dist/workflows/prd/templates/prd-template.md +10 -0
  391. package/pennyfarthing-dist/workflows/prd/workflow.yaml +42 -0
  392. package/pennyfarthing-dist/workflows/product-brief/steps/step-01-init.md +195 -0
  393. package/pennyfarthing-dist/workflows/product-brief/steps/step-01b-continue.md +180 -0
  394. package/pennyfarthing-dist/workflows/product-brief/steps/step-02-vision.md +221 -0
  395. package/pennyfarthing-dist/workflows/product-brief/steps/step-03-users.md +224 -0
  396. package/pennyfarthing-dist/workflows/product-brief/steps/step-04-metrics.md +228 -0
  397. package/pennyfarthing-dist/workflows/product-brief/steps/step-05-scope.md +243 -0
  398. package/pennyfarthing-dist/workflows/product-brief/steps/step-06-complete.md +216 -0
  399. package/pennyfarthing-dist/workflows/product-brief/templates/product-brief.template.md +10 -0
  400. package/pennyfarthing-dist/workflows/product-brief/workflow.yaml +31 -0
  401. package/pennyfarthing-dist/workflows/project-context/project-context-template.md +21 -0
  402. package/pennyfarthing-dist/workflows/project-context/steps/step-01-discover.md +206 -0
  403. package/pennyfarthing-dist/workflows/project-context/steps/step-02-generate.md +349 -0
  404. package/pennyfarthing-dist/workflows/project-context/steps/step-03-complete.md +306 -0
  405. package/pennyfarthing-dist/workflows/project-context/workflow.yaml +27 -0
  406. package/pennyfarthing-dist/workflows/project-setup/steps/step-01-discover.md +157 -0
  407. package/pennyfarthing-dist/workflows/project-setup/steps/step-02-clone-repos.md +217 -0
  408. package/pennyfarthing-dist/workflows/project-setup/steps/step-03-repos-yaml.md +159 -0
  409. package/pennyfarthing-dist/workflows/project-setup/steps/step-04-claude-md.md +186 -0
  410. package/pennyfarthing-dist/workflows/project-setup/steps/step-05-shared-context.md +185 -0
  411. package/pennyfarthing-dist/workflows/project-setup/steps/step-06-task-runner.md +279 -0
  412. package/pennyfarthing-dist/workflows/project-setup/steps/step-07-theme.md +200 -0
  413. package/pennyfarthing-dist/workflows/project-setup/steps/step-08-theme-packs.md +142 -0
  414. package/pennyfarthing-dist/workflows/project-setup/steps/step-09-cyclist.md +245 -0
  415. package/pennyfarthing-dist/workflows/project-setup/steps/step-10-complete.md +204 -0
  416. package/pennyfarthing-dist/workflows/project-setup/workflow.yaml +41 -0
  417. package/pennyfarthing-dist/workflows/quick-dev/steps/step-01-mode-detection.md +177 -0
  418. package/pennyfarthing-dist/workflows/quick-dev/steps/step-02-context-gathering.md +143 -0
  419. package/pennyfarthing-dist/workflows/quick-dev/steps/step-03-execute.md +138 -0
  420. package/pennyfarthing-dist/workflows/quick-dev/steps/step-04-self-check.md +135 -0
  421. package/pennyfarthing-dist/workflows/quick-dev/steps/step-05-adversarial-review.md +129 -0
  422. package/pennyfarthing-dist/workflows/quick-dev/steps/step-06-resolve-findings.md +163 -0
  423. package/pennyfarthing-dist/workflows/quick-dev/workflow.yaml +27 -0
  424. package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +201 -0
  425. package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +156 -0
  426. package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +140 -0
  427. package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +203 -0
  428. package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +74 -0
  429. package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +27 -0
  430. package/pennyfarthing-dist/workflows/release/steps/step-01-preflight.md +105 -0
  431. package/pennyfarthing-dist/workflows/release/steps/step-02-bump.md +95 -0
  432. package/pennyfarthing-dist/workflows/release/steps/step-03-changelog.md +125 -0
  433. package/pennyfarthing-dist/workflows/release/steps/step-04-readme.md +101 -0
  434. package/pennyfarthing-dist/workflows/release/steps/step-05-claude-md.md +102 -0
  435. package/pennyfarthing-dist/workflows/release/steps/step-06-retro.md +59 -0
  436. package/pennyfarthing-dist/workflows/release/steps/step-07-commit.md +109 -0
  437. package/pennyfarthing-dist/workflows/release/steps/step-08-merge.md +65 -0
  438. package/pennyfarthing-dist/workflows/release/steps/step-09-push.md +75 -0
  439. package/pennyfarthing-dist/workflows/release/steps/step-10-publish.md +93 -0
  440. package/pennyfarthing-dist/workflows/release/steps/step-11-finalize.md +71 -0
  441. package/pennyfarthing-dist/workflows/release.yaml +62 -0
  442. package/pennyfarthing-dist/workflows/research/steps-domain/step-01-init.md +159 -0
  443. package/pennyfarthing-dist/workflows/research/steps-domain/step-02-domain-analysis.md +253 -0
  444. package/pennyfarthing-dist/workflows/research/steps-domain/step-03-competitive-landscape.md +263 -0
  445. package/pennyfarthing-dist/workflows/research/steps-domain/step-04-regulatory-focus.md +232 -0
  446. package/pennyfarthing-dist/workflows/research/steps-domain/step-05-technical-trends.md +260 -0
  447. package/pennyfarthing-dist/workflows/research/steps-domain/step-06-research-synthesis.md +477 -0
  448. package/pennyfarthing-dist/workflows/research/steps-market/step-01-init.md +205 -0
  449. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-behavior.md +262 -0
  450. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-insights.md +227 -0
  451. package/pennyfarthing-dist/workflows/research/steps-market/step-03-customer-pain-points.md +275 -0
  452. package/pennyfarthing-dist/workflows/research/steps-market/step-04-customer-decisions.md +286 -0
  453. package/pennyfarthing-dist/workflows/research/steps-market/step-05-competitive-analysis.md +203 -0
  454. package/pennyfarthing-dist/workflows/research/steps-market/step-06-research-completion.md +510 -0
  455. package/pennyfarthing-dist/workflows/research/steps-technical/step-01-init.md +159 -0
  456. package/pennyfarthing-dist/workflows/research/steps-technical/step-02-technical-overview.md +264 -0
  457. package/pennyfarthing-dist/workflows/research/steps-technical/step-03-integration-patterns.md +274 -0
  458. package/pennyfarthing-dist/workflows/research/steps-technical/step-04-architectural-patterns.md +228 -0
  459. package/pennyfarthing-dist/workflows/research/steps-technical/step-05-implementation-research.md +267 -0
  460. package/pennyfarthing-dist/workflows/research/steps-technical/step-06-research-synthesis.md +522 -0
  461. package/pennyfarthing-dist/workflows/research/templates/research.template.md +29 -0
  462. package/pennyfarthing-dist/workflows/research/workflow.yaml +45 -0
  463. package/pennyfarthing-dist/workflows/retrospective/checklist.md +31 -0
  464. package/pennyfarthing-dist/workflows/retrospective/instructions.md +1443 -0
  465. package/pennyfarthing-dist/workflows/retrospective/workflow.yaml +50 -0
  466. package/pennyfarthing-dist/workflows/sprint-planning/checklist.md +33 -0
  467. package/pennyfarthing-dist/workflows/sprint-planning/sprint-status-template.yaml +55 -0
  468. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-01-parse-epic-files.md +69 -0
  469. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-02-build-sprint-status.md +61 -0
  470. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-03-status-detection.md +80 -0
  471. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-04-generate-status-file.md +90 -0
  472. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-05-validate-and-report.md +78 -0
  473. package/pennyfarthing-dist/workflows/sprint-planning/workflow.yaml +34 -0
  474. package/pennyfarthing-dist/workflows/tdd.yaml +50 -0
  475. package/pennyfarthing-dist/workflows/trivial.yaml +40 -0
  476. package/pennyfarthing-dist/workflows/ux-design/steps/step-01-init.md +141 -0
  477. package/pennyfarthing-dist/workflows/ux-design/steps/step-01b-continue.md +133 -0
  478. package/pennyfarthing-dist/workflows/ux-design/steps/step-02-discovery.md +196 -0
  479. package/pennyfarthing-dist/workflows/ux-design/steps/step-03-core-experience.md +222 -0
  480. package/pennyfarthing-dist/workflows/ux-design/steps/step-04-emotional-response.md +225 -0
  481. package/pennyfarthing-dist/workflows/ux-design/steps/step-05-inspiration.md +240 -0
  482. package/pennyfarthing-dist/workflows/ux-design/steps/step-06-design-system.md +258 -0
  483. package/pennyfarthing-dist/workflows/ux-design/steps/step-07-defining-experience.md +260 -0
  484. package/pennyfarthing-dist/workflows/ux-design/steps/step-08-visual-foundation.md +230 -0
  485. package/pennyfarthing-dist/workflows/ux-design/steps/step-09-design-directions.md +230 -0
  486. package/pennyfarthing-dist/workflows/ux-design/steps/step-10-user-journeys.md +247 -0
  487. package/pennyfarthing-dist/workflows/ux-design/steps/step-11-component-strategy.md +254 -0
  488. package/pennyfarthing-dist/workflows/ux-design/steps/step-12-ux-patterns.md +243 -0
  489. package/pennyfarthing-dist/workflows/ux-design/steps/step-13-responsive-accessibility.md +270 -0
  490. package/pennyfarthing-dist/workflows/ux-design/steps/step-14-complete.md +234 -0
  491. package/pennyfarthing-dist/workflows/ux-design/ux-design-template.md +13 -0
  492. package/pennyfarthing-dist/workflows/ux-design/workflow.yaml +41 -0
@@ -0,0 +1,106 @@
1
+ #!/bin/bash
2
+ #
3
+ # Bell Mode PostToolUse Hook (Story MSSCI-12275)
4
+ #
5
+ # This hook is called by Claude Code after each tool execution.
6
+ # When bell mode is enabled and there are queued messages, it returns
7
+ # the first queued message as additionalContext to be injected into
8
+ # Claude's next API call.
9
+ #
10
+ # Configuration files:
11
+ # .pennyfarthing/config.local.yaml - workflow.bell_mode: true/false
12
+ # .pennyfarthing/bell-queue.json - [{ "text": "...", "images": [...] }, ...]
13
+ #
14
+ # Output format (when injecting):
15
+ # {
16
+ # "hookSpecificOutput": {
17
+ # "hookEventName": "PostToolUse",
18
+ # "additionalContext": "User feedback: <message>"
19
+ # }
20
+ # }
21
+ #
22
+ # Output when disabled or queue empty: (nothing - exit 0)
23
+
24
+ # Find project root (walk up to find .pennyfarthing)
25
+ PROJECT_ROOT="$PWD"
26
+ while [[ "$PROJECT_ROOT" != "/" ]]; do
27
+ if [[ -d "$PROJECT_ROOT/.pennyfarthing" ]]; then
28
+ break
29
+ fi
30
+ PROJECT_ROOT="$(dirname "$PROJECT_ROOT")"
31
+ done
32
+
33
+ if [[ ! -d "$PROJECT_ROOT/.pennyfarthing" ]]; then
34
+ # No .pennyfarthing directory found - exit silently
35
+ exit 0
36
+ fi
37
+
38
+ CONFIG_LOCAL_YAML="$PROJECT_ROOT/.pennyfarthing/config.local.yaml"
39
+ BELL_QUEUE_FILE="$PROJECT_ROOT/.pennyfarthing/bell-queue.json"
40
+
41
+ # Check if bell mode is enabled in config.local.yaml
42
+ if [[ ! -f "$CONFIG_LOCAL_YAML" ]]; then
43
+ exit 0
44
+ fi
45
+
46
+ # Parse YAML to check workflow.bell_mode - look for "bell_mode: true"
47
+ # This handles both "bell_mode: true" and " bell_mode: true" (indented under workflow)
48
+ ENABLED=$(grep -E '^\s*bell_mode:\s*true' "$CONFIG_LOCAL_YAML" 2>/dev/null || true)
49
+ if [[ -z "$ENABLED" ]]; then
50
+ exit 0
51
+ fi
52
+
53
+ # Check if queue file exists and has messages
54
+ if [[ ! -f "$BELL_QUEUE_FILE" ]]; then
55
+ exit 0
56
+ fi
57
+
58
+ # Read queue and check if non-empty
59
+ QUEUE_CONTENT=$(cat "$BELL_QUEUE_FILE" 2>/dev/null)
60
+ if [[ -z "$QUEUE_CONTENT" ]] || [[ "$QUEUE_CONTENT" == "[]" ]]; then
61
+ exit 0
62
+ fi
63
+
64
+ # Extract first message text using simple parsing
65
+ # The queue format is: [{"text":"...","images":[...]}, ...]
66
+ FIRST_MESSAGE_TEXT=$(echo "$QUEUE_CONTENT" | sed -n 's/.*"text"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
67
+
68
+ if [[ -z "$FIRST_MESSAGE_TEXT" ]]; then
69
+ exit 0
70
+ fi
71
+
72
+ # Get Cyclist port (if running)
73
+ CYCLIST_PORT=""
74
+ PORT_FILE="$PROJECT_ROOT/.cyclist-port"
75
+ if [[ -f "$PORT_FILE" ]]; then
76
+ CYCLIST_PORT=$(cat "$PORT_FILE" 2>/dev/null)
77
+ fi
78
+
79
+ # Output the hook response JSON
80
+ cat << EOF
81
+ {
82
+ "hookSpecificOutput": {
83
+ "hookEventName": "PostToolUse",
84
+ "additionalContext": "User feedback: $FIRST_MESSAGE_TEXT"
85
+ }
86
+ }
87
+ EOF
88
+
89
+ # Remove the first message from the queue and notify Cyclist
90
+ # Run in background to avoid blocking hook response
91
+ (
92
+ # Dequeue using jq if available
93
+ if command -v jq &> /dev/null; then
94
+ jq 'if length > 0 then .[1:] else [] end' "$BELL_QUEUE_FILE" > "$BELL_QUEUE_FILE.tmp" 2>/dev/null && mv "$BELL_QUEUE_FILE.tmp" "$BELL_QUEUE_FILE"
95
+ fi
96
+
97
+ # Notify Cyclist browser to dequeue and display the message
98
+ if [[ -n "$CYCLIST_PORT" ]] && [[ "$CYCLIST_PORT" =~ ^[0-9]+$ ]]; then
99
+ curl -s -X POST "http://localhost:$CYCLIST_PORT/api/bell-consumed" \
100
+ -H "Content-Type: application/json" \
101
+ -d "{\"text\": \"$FIRST_MESSAGE_TEXT\"}" \
102
+ >/dev/null 2>&1 || true
103
+ fi
104
+ ) &
105
+
106
+ exit 0
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env zsh
2
+ # Context circuit breaker hook: Block tool execution at 85% context usage
3
+ # Called by Claude Code before tool calls (PreToolUse)
4
+ #
5
+ # Input: JSON via stdin with tool_name, tool_input, session_id
6
+ # Output: Exit 0 to allow, Exit 2 to block (stderr shown to Claude)
7
+ #
8
+ # This hook provides a hard stop when context is critically high,
9
+ # unlike context-warning.sh which only warns.
10
+ #
11
+ # When triggered, automatically saves the active agent to a checkpoint
12
+ # so /continue-session can restore it with FULL tier.
13
+
14
+ # Read stdin to get session_id (required by hook protocol)
15
+ INPUT=$(cat)
16
+
17
+ # Script location for sibling script references
18
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
19
+
20
+ # Get context percentage from check-context.sh
21
+ CONTEXT_SCRIPT="$SCRIPT_DIR/../check-context.sh"
22
+ if [[ ! -x "$CONTEXT_SCRIPT" ]]; then
23
+ # graceful degradation: if check-context.sh not found, allow the tool
24
+ exit 0
25
+ fi
26
+
27
+ # Run check-context.sh and parse output
28
+ eval "$("$CONTEXT_SCRIPT" 2>/dev/null)" 2>/dev/null
29
+
30
+ # graceful degradation: if we can't get context, allow the tool
31
+ if [[ -z "$CONTEXT_PERCENT" ]] || [[ "$CONTEXT_PERCENT" == "null" ]]; then
32
+ exit 0
33
+ fi
34
+
35
+ # Load critical threshold (default 80%)
36
+ CRITICAL_THRESHOLD="${CRITICAL_THRESHOLD:-80}"
37
+
38
+ # Check if at or above critical threshold
39
+ if [[ "$CONTEXT_PERCENT" -ge "$CRITICAL_THRESHOLD" ]] 2>/dev/null; then
40
+ # Auto-save active agent to checkpoint before blocking
41
+ # This allows /continue-session to restore with FULL tier
42
+ source "$SCRIPT_DIR/../lib/checkpoint.sh" 2>/dev/null || true
43
+
44
+ # Get session_id from input JSON
45
+ SESSION_ID=""
46
+ if command -v jq &>/dev/null && [[ -n "$INPUT" ]]; then
47
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
48
+ fi
49
+
50
+ # Look up active agent for this session
51
+ ACTIVE_AGENT=""
52
+ AGENT_FILE="${CLAUDE_PROJECT_DIR:-.}/.session/agents/${SESSION_ID}"
53
+ if [[ -n "$SESSION_ID" && -f "$AGENT_FILE" ]]; then
54
+ ACTIVE_AGENT=$(cat "$AGENT_FILE" 2>/dev/null)
55
+ fi
56
+
57
+ # Save agent checkpoint if we found one
58
+ if [[ -n "$ACTIVE_AGENT" ]]; then
59
+ checkpoint_save "circuit_breaker_agent" "$ACTIVE_AGENT" 2>/dev/null || true
60
+ fi
61
+
62
+ # Send error message to stderr (Claude will see this)
63
+ cat >&2 << EOF
64
+ CONTEXT CIRCUIT BREAKER TRIGGERED
65
+
66
+ Context usage: ${CONTEXT_PERCENT}% - CRITICAL (threshold: ${CRITICAL_THRESHOLD}%)
67
+
68
+ Tool execution BLOCKED. You must stop and hand off.
69
+ EOF
70
+
71
+ # Include agent info if available
72
+ if [[ -n "$ACTIVE_AGENT" ]]; then
73
+ cat >&2 << EOF
74
+
75
+ Active agent saved: ${ACTIVE_AGENT}
76
+ The agent will be restored with FULL context when you run /continue-session.
77
+ EOF
78
+ fi
79
+
80
+ cat >&2 << EOF
81
+
82
+ Required actions:
83
+ 1. Commit any pending changes
84
+ 2. Tell user to start fresh session with /continue-session
85
+
86
+ DO NOT attempt further tool calls. This is a hard stop.
87
+
88
+ To resume later: /continue-session
89
+ EOF
90
+ # Exit 2 blocks the tool execution
91
+ exit 2
92
+ fi
93
+
94
+ # Below threshold: allow the tool
95
+ exit 0
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env zsh
2
+ # Context warning hook: Warn agent when context usage is high
3
+ # Called by Claude Code before tool calls (PreToolUse)
4
+ #
5
+ # Input: JSON via stdin with tool_name, tool_input
6
+ # Output: Warning message to stdout if context > 60%
7
+ # Always exits 0 (warning only, never blocks)
8
+
9
+ # Read and discard stdin (required by hook protocol)
10
+ cat > /dev/null
11
+
12
+ # Script location for sibling script references
13
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
14
+
15
+ # Get context percentage from check-context.sh
16
+ CONTEXT_SCRIPT="$SCRIPT_DIR/../check-context.sh"
17
+ if [[ ! -x "$CONTEXT_SCRIPT" ]]; then
18
+ exit 0 # Can't check, allow silently
19
+ fi
20
+
21
+ # Run check-context.sh and parse output
22
+ eval "$("$CONTEXT_SCRIPT" 2>/dev/null)" 2>/dev/null
23
+
24
+ # Check if we got a valid percentage
25
+ if [[ -z "$CONTEXT_PERCENT" ]] || [[ "$CONTEXT_PERCENT" == "null" ]]; then
26
+ exit 0 # Can't determine, allow silently
27
+ fi
28
+
29
+ # Load thresholds from settings (defaults match check-context.sh)
30
+ WARNING_THRESHOLD="${WARNING_THRESHOLD:-60}"
31
+ CRITICAL_THRESHOLD="${CRITICAL_THRESHOLD:-85}"
32
+
33
+ # Output warning if above threshold
34
+ if [[ "$CONTEXT_PERCENT" -ge "$CRITICAL_THRESHOLD" ]] 2>/dev/null; then
35
+ cat << EOF
36
+
37
+ ---
38
+ CONTEXT WARNING: ${CONTEXT_PERCENT}% (CRITICAL)
39
+
40
+ Context usage is critically high. Recommended actions:
41
+ 1. Complete current task immediately
42
+ 2. Commit any pending changes
43
+ 3. Hand off to next agent or ask user to start fresh session
44
+
45
+ Do NOT start new subtasks. Wrap up and hand off.
46
+ ---
47
+
48
+ EOF
49
+ elif [[ "$CONTEXT_PERCENT" -ge "$WARNING_THRESHOLD" ]] 2>/dev/null; then
50
+ cat << EOF
51
+
52
+ ---
53
+ CONTEXT WARNING: ${CONTEXT_PERCENT}%
54
+
55
+ Context usage is high. Consider:
56
+ - Wrapping up current task soon
57
+ - Preparing for handoff to next agent
58
+ - Avoiding large file reads or complex operations
59
+ ---
60
+
61
+ EOF
62
+ fi
63
+
64
+ # Always allow the tool (we're warning, not blocking)
65
+ exit 0
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ # otel-auto-config.sh - Auto-configure OTEL for Cyclist web mode (Story 20-1)
3
+ #
4
+ # This hook checks for a .cyclist-port file in the project directory.
5
+ # If found, it sets the OTEL environment variables to connect Claude Code
6
+ # telemetry to the running Cyclist server.
7
+ #
8
+ # Usage: Source this script early in Claude Code startup to enable auto-config.
9
+ # source /path/to/otel-auto-config.sh
10
+ #
11
+ # Prerequisites:
12
+ # - Cyclist must be running in web mode (writes .cyclist-port file)
13
+ # - CLAUDE_PROJECT_DIR must be set (standard in Claude Code environment)
14
+
15
+ # Determine project directory
16
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
17
+ PORT_FILE="$PROJECT_DIR/.cyclist-port"
18
+
19
+ # Check if port file exists
20
+ if [[ -f "$PORT_FILE" ]]; then
21
+ # Read the port number
22
+ PORT=$(cat "$PORT_FILE" 2>/dev/null)
23
+
24
+ # Validate port is a number
25
+ if [[ "$PORT" =~ ^[0-9]+$ ]]; then
26
+ # Set OTEL environment variables
27
+ export OTEL_EXPORTER_OTLP_PROTOCOL="http/json"
28
+ export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:$PORT"
29
+
30
+ # Optional: Log for debugging (can be silenced by setting CYCLIST_QUIET=1)
31
+ if [[ -z "$CYCLIST_QUIET" ]]; then
32
+ echo "[otel-auto-config] Configured OTEL to http://localhost:$PORT" >&2
33
+ fi
34
+ fi
35
+ fi
@@ -0,0 +1,150 @@
1
+ #!/bin/bash
2
+ # post-merge.sh - Git hook for automatic sprint YAML updates after PR merge
3
+ # Story 8-1: Git Hook for PR Merge Detection
4
+ #
5
+ # This hook runs after git pull or git merge operations, detecting when a
6
+ # story branch is merged and automatically updating the sprint YAML status.
7
+ #
8
+ # Installation:
9
+ # Installed to .git/hooks/post-merge by pennyfarthing init or doctor --fix
10
+ #
11
+ # Dependencies:
12
+ # - yq (for YAML manipulation)
13
+ # - sprint-common.sh (for shared sprint functions)
14
+
15
+ set -uo pipefail
16
+
17
+ # Self-locate (resolve symlink first for .git/hooks/ symlinks)
18
+ REAL_SCRIPT="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
19
+ source "$(dirname "$REAL_SCRIPT")/../lib/find-root.sh"
20
+
21
+ # PROJECT_ROOT is now set by find-root.sh
22
+ SESSION_DIR="$PROJECT_ROOT/.session"
23
+ SPRINT_FILE="$PROJECT_ROOT/sprint/current-sprint.yaml"
24
+
25
+ # Source sprint-common.sh for shared functions
26
+ SPRINT_COMMON="$PROJECT_ROOT/.pennyfarthing/scripts/sprint/sprint-common.sh"
27
+ if [[ -f "$SPRINT_COMMON" ]]; then
28
+ # shellcheck source=/dev/null
29
+ source "$SPRINT_COMMON"
30
+ fi
31
+
32
+ # extract_story_id BRANCH_NAME
33
+ # Extract story ID from branch name pattern feat/X-Y-*
34
+ # Returns: X-Y (e.g., "8-1" from "feat/8-1-merge-detection")
35
+ # Returns empty for non-matching branches
36
+ extract_story_id() {
37
+ local branch="$1"
38
+
39
+ # Match pattern: feat/EPIC-STORY-description or feat/EPIC-STORY
40
+ if [[ "$branch" =~ ^feat/([0-9]+-[0-9]+) ]]; then
41
+ echo "${BASH_REMATCH[1]}"
42
+ fi
43
+ # Returns empty string for non-matching patterns
44
+ }
45
+
46
+ # update_story_status STORY_ID NEW_STATUS
47
+ # Update story status in sprint YAML and add completed date
48
+ # Uses yq for YAML manipulation
49
+ update_story_status() {
50
+ local story_id="$1"
51
+ local new_status="${2:-done}"
52
+ local completed_date
53
+ completed_date=$(date +%Y-%m-%d)
54
+
55
+ if [[ ! -f "$SPRINT_FILE" ]]; then
56
+ return 1
57
+ fi
58
+
59
+ # Check if yq is available
60
+ if ! command -v yq &>/dev/null; then
61
+ echo "Warning: yq not found, cannot update sprint YAML" >&2
62
+ return 1
63
+ fi
64
+
65
+ # Extract epic and story numbers
66
+ local epic_num="${story_id%%-*}"
67
+ local story_num="${story_id#*-}"
68
+
69
+ # Update status and add completed date using yq
70
+ yq eval -i "
71
+ (.epics[] | select(.id == \"$epic_num\") | .stories[] | select(.id == \"$story_num\")).status = \"$new_status\" |
72
+ (.epics[] | select(.id == \"$epic_num\") | .stories[] | select(.id == \"$story_num\")).completed = \"$completed_date\"
73
+ " "$SPRINT_FILE"
74
+
75
+ return $?
76
+ }
77
+
78
+ # log_reconciliation STORY_ID MESSAGE
79
+ # Log reconciliation event to .session/ directory
80
+ log_reconciliation() {
81
+ local story_id="$1"
82
+ local message="${2:-Merge detected}"
83
+ local timestamp
84
+ timestamp=$(date +"%Y-%m-%d %H:%M:%S")
85
+
86
+ # Ensure session directory exists
87
+ mkdir -p "$SESSION_DIR"
88
+
89
+ local log_file="$SESSION_DIR/reconciliation.log"
90
+
91
+ echo "[$timestamp] Story $story_id: $message" >> "$log_file"
92
+ }
93
+
94
+ # Main hook logic
95
+ main() {
96
+ # Get the current branch after merge
97
+ local current_branch
98
+ current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
99
+
100
+ # Only process if we're on develop or main (after a PR merge)
101
+ if [[ "$current_branch" != "develop" && "$current_branch" != "main" ]]; then
102
+ exit 0
103
+ fi
104
+
105
+ # Get the branches that were just merged
106
+ # The reflog shows what was merged: the previous HEAD and the merged commit
107
+ local merged_refs
108
+ merged_refs=$(git reflog -1 --format='%gs' 2>/dev/null)
109
+
110
+ # Check if this was a merge operation
111
+ if [[ ! "$merged_refs" =~ merge ]]; then
112
+ # Could be a pull with fast-forward - check for merged branches
113
+ # Look at recently merged branches by checking merge commits
114
+ :
115
+ fi
116
+
117
+ # Find recently merged feature branches by examining merge commits
118
+ local merge_commits
119
+ merge_commits=$(git log --merges --oneline -10 --since="5 minutes ago" 2>/dev/null)
120
+
121
+ # Extract branch names from merge commits
122
+ while IFS= read -r commit_line; do
123
+ # Parse "Merge pull request #X from user/feat/X-Y-description"
124
+ # or "Merge branch 'feat/X-Y-description'"
125
+ local branch_name=""
126
+
127
+ if [[ "$commit_line" =~ feat/([0-9]+-[0-9]+[a-zA-Z0-9-]*) ]]; then
128
+ branch_name="feat/${BASH_REMATCH[1]}"
129
+ fi
130
+
131
+ if [[ -n "$branch_name" ]]; then
132
+ local story_id
133
+ story_id=$(extract_story_id "$branch_name")
134
+
135
+ if [[ -n "$story_id" ]]; then
136
+ # Update sprint YAML
137
+ if update_story_status "$story_id" "done"; then
138
+ log_reconciliation "$story_id" "Status updated to 'done' after merge (branch: $branch_name)"
139
+ else
140
+ log_reconciliation "$story_id" "Failed to update status (branch: $branch_name)"
141
+ fi
142
+ fi
143
+ fi
144
+ done <<< "$merge_commits"
145
+ }
146
+
147
+ # Only run main when executed directly (not when sourced for testing)
148
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
149
+ main "$@"
150
+ fi
@@ -0,0 +1,190 @@
1
+ #!/bin/bash
2
+ # pre-commit.sh - Git hook to enforce branch protection and agent validation
3
+ #
4
+ # Checks:
5
+ # 1. Prevents direct commits to protected branches (main, develop)
6
+ # Exception: sprint/ folder commits allowed on develop
7
+ # 2. Validates agent files when pennyfarthing-dist/agents/*.md is modified
8
+ # 3. Validates sprint YAML files when sprint/*.yaml is modified
9
+ #
10
+ # Installation:
11
+ # Installed to .git/hooks/pre-commit by pennyfarthing init or doctor --fix
12
+ # Or symlink: ln -sf ../../pennyfarthing-dist/scripts/hooks/pre-commit.sh .git/hooks/pre-commit
13
+
14
+ set -uo pipefail
15
+
16
+ # Find project root
17
+ # Try find-root.sh via symlink resolution first, then fall back to .git location
18
+ REAL_SCRIPT="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
19
+ FIND_ROOT="$(dirname "$REAL_SCRIPT")/../lib/find-root.sh"
20
+ if [[ -f "$FIND_ROOT" ]]; then
21
+ source "$FIND_ROOT"
22
+ else
23
+ # Running as a copy in .git/hooks/ — derive PROJECT_ROOT from git dir
24
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")/../.." && pwd)"
25
+ export PROJECT_ROOT
26
+ fi
27
+
28
+ # =============================================================================
29
+ # Check 1: Branch Protection
30
+ # =============================================================================
31
+
32
+ BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
33
+ PROTECTED_BRANCHES="^(main|develop)$"
34
+
35
+ if [[ $BRANCH =~ $PROTECTED_BRANCHES ]]; then
36
+ # Special case: Allow sprint/ folder commits on develop branch
37
+ if [[ $BRANCH == "develop" ]]; then
38
+ STAGED_FILES=$(git diff --cached --name-only)
39
+ NON_SPRINT_FILES=$(echo "$STAGED_FILES" | grep -v "^sprint/")
40
+
41
+ # If all staged files are in sprint/, allow the commit
42
+ if [ -z "$NON_SPRINT_FILES" ] && [ -n "$STAGED_FILES" ]; then
43
+ # Continue to agent validation check
44
+ :
45
+ else
46
+ echo ""
47
+ echo "COMMIT BLOCKED"
48
+ echo ""
49
+ echo "You are trying to commit directly to: $BRANCH"
50
+ echo "This violates the git workflow rules."
51
+ echo ""
52
+ echo "Protected branches: main, develop"
53
+ echo ""
54
+ echo "What to do:"
55
+ echo "1. Create a feature branch:"
56
+ echo " git checkout -b <type>/<epic-story>-<description>"
57
+ echo ""
58
+ echo "2. Example:"
59
+ echo " git checkout -b feat/8-2-add-authentication"
60
+ echo ""
61
+ echo "3. Then commit your changes on the feature branch"
62
+ echo ""
63
+ echo "Exception: Sprint tracking files (sprint/*) can be committed to develop"
64
+ echo ""
65
+ exit 1
66
+ fi
67
+ else
68
+ echo ""
69
+ echo "COMMIT BLOCKED - Cannot commit directly to $BRANCH"
70
+ echo ""
71
+ exit 1
72
+ fi
73
+ fi
74
+
75
+ # =============================================================================
76
+ # Check 2: Agent File Validation
77
+ # =============================================================================
78
+
79
+ STAGED_FILES=$(git diff --cached --name-only 2>/dev/null || true)
80
+ AGENT_FILES=$(echo "$STAGED_FILES" | grep "^pennyfarthing-dist/agents/.*\.md$" || true)
81
+
82
+ if [[ -n "$AGENT_FILES" ]]; then
83
+ echo "Agent files staged for commit:"
84
+ echo "$AGENT_FILES" | sed 's/^/ /'
85
+ echo ""
86
+
87
+ VALIDATOR="$PROJECT_ROOT/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh"
88
+
89
+ if [[ -x "$VALIDATOR" ]]; then
90
+ echo "Running agent schema validation..."
91
+ echo ""
92
+
93
+ if ! "$VALIDATOR"; then
94
+ echo ""
95
+ echo "COMMIT BLOCKED - Agent validation failed"
96
+ echo ""
97
+ echo "Fix the validation errors above and try again."
98
+ echo "Run 'just validate-agents -v' for detailed output."
99
+ echo ""
100
+ exit 1
101
+ fi
102
+
103
+ echo ""
104
+ echo "✓ Agent validation passed"
105
+ else
106
+ echo "Warning: Agent validator not found at $VALIDATOR"
107
+ echo "Skipping agent validation."
108
+ fi
109
+ fi
110
+
111
+ # =============================================================================
112
+ # Check 3: Sprint YAML Validation
113
+ # =============================================================================
114
+
115
+ SPRINT_YAML_FILES=$(git diff --cached --name-only -- 'sprint/*.yaml' 'sprint/archive/*.yaml' 2>/dev/null \
116
+ | grep -v 'sprint-template\.yaml$' \
117
+ | grep -v 'sprint/completed\.yaml$' || true)
118
+
119
+ if [[ -n "$SPRINT_YAML_FILES" ]]; then
120
+ echo "Sprint YAML files staged for commit:"
121
+ echo "$SPRINT_YAML_FILES" | sed 's/^/ /'
122
+ echo ""
123
+
124
+ # Find python3
125
+ PYTHON=""
126
+ if command -v python3 &>/dev/null; then
127
+ PYTHON="python3"
128
+ elif command -v python &>/dev/null; then
129
+ PYTHON="python"
130
+ fi
131
+
132
+ if [[ -z "$PYTHON" ]]; then
133
+ echo "Warning: Python not found, skipping sprint YAML validation."
134
+ else
135
+ echo "Running sprint YAML validation..."
136
+
137
+ # Set PYTHONPATH to include pennyfarthing source
138
+ PYTHONPATH_ORIG="${PYTHONPATH:-}"
139
+ if [[ -d "$PROJECT_ROOT/pennyfarthing" ]]; then
140
+ export PYTHONPATH="$PROJECT_ROOT/pennyfarthing${PYTHONPATH_ORIG:+:$PYTHONPATH_ORIG}"
141
+ fi
142
+
143
+ VALIDATION_FAILED=0
144
+ while IFS= read -r yaml_file; do
145
+ FULL_PATH="$PROJECT_ROOT/$yaml_file"
146
+ if [[ ! -f "$FULL_PATH" ]]; then
147
+ echo " Warning: $yaml_file not found (deleted?), skipping"
148
+ continue
149
+ fi
150
+ if ! $PYTHON -c "
151
+ import sys
152
+ from pathlib import Path
153
+ from pennyfarthing_scripts.sprint.validate_cmd import validate_sprint_yaml
154
+ result = validate_sprint_yaml(Path(sys.argv[1]))
155
+ if result.errors:
156
+ for e in result.errors:
157
+ line = f' (line {e.line})' if e.line else ''
158
+ print(f' ERROR [{e.category}]{line}: {e.message}', file=sys.stderr)
159
+ if result.format_issues:
160
+ for f in result.format_issues:
161
+ print(f' FORMAT: {f.message}', file=sys.stderr)
162
+ sys.exit(0 if result.valid else 1)
163
+ " "$FULL_PATH"; then
164
+ VALIDATION_FAILED=1
165
+ fi
166
+ done <<< "$SPRINT_YAML_FILES"
167
+
168
+ # Restore PYTHONPATH
169
+ if [[ -n "$PYTHONPATH_ORIG" ]]; then
170
+ export PYTHONPATH="$PYTHONPATH_ORIG"
171
+ else
172
+ unset PYTHONPATH
173
+ fi
174
+
175
+ if [[ $VALIDATION_FAILED -eq 1 ]]; then
176
+ echo ""
177
+ echo "COMMIT BLOCKED - Sprint YAML validation failed"
178
+ echo ""
179
+ echo "Fix: Review errors above, then run:"
180
+ echo " python3 -m pennyfarthing_scripts.sprint.validate_cmd --fix <file>"
181
+ echo ""
182
+ exit 1
183
+ fi
184
+
185
+ echo "✓ Sprint YAML validation passed"
186
+ echo ""
187
+ fi
188
+ fi
189
+
190
+ exit 0