@pennyfarthing/core 7.9.3 → 7.9.5

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 (538) hide show
  1. package/package.json +1 -1
  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 +180 -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 +284 -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 +7 -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 +178 -0
  27. package/pennyfarthing-dist/commands/close-epic.md +139 -0
  28. package/pennyfarthing-dist/commands/continue-session.md +184 -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 +7 -0
  32. package/pennyfarthing-dist/commands/devops.md +7 -0
  33. package/pennyfarthing-dist/commands/git-cleanup.md +51 -0
  34. package/pennyfarthing-dist/commands/health-check.md +141 -0
  35. package/pennyfarthing-dist/commands/help.md +264 -0
  36. package/pennyfarthing-dist/commands/job-fair.md +102 -0
  37. package/pennyfarthing-dist/commands/list-themes.md +21 -0
  38. package/pennyfarthing-dist/commands/orchestrator.md +7 -0
  39. package/pennyfarthing-dist/commands/parallel-work.md +71 -0
  40. package/pennyfarthing-dist/commands/party-mode.md +77 -0
  41. package/pennyfarthing-dist/commands/permissions.md +193 -0
  42. package/pennyfarthing-dist/commands/pm.md +7 -0
  43. package/pennyfarthing-dist/commands/prime.md +140 -0
  44. package/pennyfarthing-dist/commands/release.md +58 -0
  45. package/pennyfarthing-dist/commands/repo-status.md +49 -0
  46. package/pennyfarthing-dist/commands/retro.md +200 -0
  47. package/pennyfarthing-dist/commands/reviewer.md +7 -0
  48. package/pennyfarthing-dist/commands/run-ci.md +116 -0
  49. package/pennyfarthing-dist/commands/set-theme.md +56 -0
  50. package/pennyfarthing-dist/commands/show-theme.md +21 -0
  51. package/pennyfarthing-dist/commands/sm.md +7 -0
  52. package/pennyfarthing-dist/commands/solo.md +447 -0
  53. package/pennyfarthing-dist/commands/sprint-planning.md +109 -0
  54. package/pennyfarthing-dist/commands/sprint.md +133 -0
  55. package/pennyfarthing-dist/commands/standalone.md +194 -0
  56. package/pennyfarthing-dist/commands/start-epic.md +168 -0
  57. package/pennyfarthing-dist/commands/sync-epic-to-jira.md +184 -0
  58. package/pennyfarthing-dist/commands/sync-work-with-sprint.md +373 -0
  59. package/pennyfarthing-dist/commands/tea.md +7 -0
  60. package/pennyfarthing-dist/commands/tech-writer.md +7 -0
  61. package/pennyfarthing-dist/commands/theme-maker.md +676 -0
  62. package/pennyfarthing-dist/commands/update-domain-docs.md +83 -0
  63. package/pennyfarthing-dist/commands/ux-designer.md +7 -0
  64. package/pennyfarthing-dist/commands/work.md +23 -0
  65. package/pennyfarthing-dist/commands/workflow.md +21 -0
  66. package/pennyfarthing-dist/guides/agent-behavior.md +311 -0
  67. package/pennyfarthing-dist/guides/agent-coordination.md +480 -0
  68. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +432 -0
  69. package/pennyfarthing-dist/guides/agent-template-strategic.md +148 -0
  70. package/pennyfarthing-dist/guides/agent-template-tactical.md +162 -0
  71. package/pennyfarthing-dist/guides/hooks.md +230 -0
  72. package/pennyfarthing-dist/guides/measurement-framework.md +210 -0
  73. package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +766 -0
  74. package/pennyfarthing-dist/guides/patterns/fan-out-fan-in-pattern.md +574 -0
  75. package/pennyfarthing-dist/guides/patterns/helper-delegation-pattern.md +488 -0
  76. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +402 -0
  77. package/pennyfarthing-dist/guides/permission-protocol.md +188 -0
  78. package/pennyfarthing-dist/guides/persona-loading.md +46 -0
  79. package/pennyfarthing-dist/guides/prompt-patterns.md +338 -0
  80. package/pennyfarthing-dist/guides/scale-levels.md +114 -0
  81. package/pennyfarthing-dist/guides/session-artifacts.md +193 -0
  82. package/pennyfarthing-dist/guides/workflow-schema.md +257 -0
  83. package/pennyfarthing-dist/guides/worktree-mode.md +113 -0
  84. package/pennyfarthing-dist/guides/xml-tags.md +335 -0
  85. package/pennyfarthing-dist/output-styles/teaching.md +33 -0
  86. package/pennyfarthing-dist/output-styles/terse.md +20 -0
  87. package/pennyfarthing-dist/output-styles/verbose.md +28 -0
  88. package/pennyfarthing-dist/personas/BENCHMARK-METHODOLOGY.md +105 -0
  89. package/pennyfarthing-dist/personas/OCEAN-BENCHMARKING.md +210 -0
  90. package/pennyfarthing-dist/personas/TRAIL-OCEAN-MAPPING.md +168 -0
  91. package/pennyfarthing-dist/personas/ZEITGEIST-ANALYSIS.md +171 -0
  92. package/pennyfarthing-dist/personas/attributes.yaml +69 -0
  93. package/pennyfarthing-dist/personas/scripts/add-zeitgeist-calibrated.py +81 -0
  94. package/pennyfarthing-dist/personas/scripts/add-zeitgeist-scores.sh +56 -0
  95. package/pennyfarthing-dist/personas/themes/1984.yaml +304 -0
  96. package/pennyfarthing-dist/personas/themes/a-team.yaml +331 -0
  97. package/pennyfarthing-dist/personas/themes/agatha-christie.yaml +294 -0
  98. package/pennyfarthing-dist/personas/themes/alice-in-wonderland.yaml +324 -0
  99. package/pennyfarthing-dist/personas/themes/all-stars.yaml +326 -0
  100. package/pennyfarthing-dist/personas/themes/ancient-philosophers.yaml +312 -0
  101. package/pennyfarthing-dist/personas/themes/ancient-strategists.yaml +298 -0
  102. package/pennyfarthing-dist/personas/themes/arcane.yaml +282 -0
  103. package/pennyfarthing-dist/personas/themes/arthurian-mythos.yaml +327 -0
  104. package/pennyfarthing-dist/personas/themes/avatar-the-last-airbender.yaml +282 -0
  105. package/pennyfarthing-dist/personas/themes/babylon-5.yaml +282 -0
  106. package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +282 -0
  107. package/pennyfarthing-dist/personas/themes/better-call-saul.yaml +282 -0
  108. package/pennyfarthing-dist/personas/themes/big-lebowski.yaml +294 -0
  109. package/pennyfarthing-dist/personas/themes/black-sails.yaml +294 -0
  110. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +289 -0
  111. package/pennyfarthing-dist/personas/themes/bobiverse.yaml +282 -0
  112. package/pennyfarthing-dist/personas/themes/breaking-bad.yaml +319 -0
  113. package/pennyfarthing-dist/personas/themes/catch-22.yaml +304 -0
  114. package/pennyfarthing-dist/personas/themes/classical-composers.yaml +302 -0
  115. package/pennyfarthing-dist/personas/themes/control.yaml +201 -0
  116. package/pennyfarthing-dist/personas/themes/count-of-monte-cristo.yaml +312 -0
  117. package/pennyfarthing-dist/personas/themes/cowboy-bebop.yaml +315 -0
  118. package/pennyfarthing-dist/personas/themes/deadwood.yaml +294 -0
  119. package/pennyfarthing-dist/personas/themes/dickens.yaml +312 -0
  120. package/pennyfarthing-dist/personas/themes/discworld.yaml +334 -0
  121. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +284 -0
  122. package/pennyfarthing-dist/personas/themes/don-quixote.yaml +312 -0
  123. package/pennyfarthing-dist/personas/themes/dune.yaml +301 -0
  124. package/pennyfarthing-dist/personas/themes/enlightenment-thinkers.yaml +312 -0
  125. package/pennyfarthing-dist/personas/themes/expeditionary-force.yaml +282 -0
  126. package/pennyfarthing-dist/personas/themes/fargo.yaml +322 -0
  127. package/pennyfarthing-dist/personas/themes/film-auteurs.yaml +304 -0
  128. package/pennyfarthing-dist/personas/themes/firefly.yaml +320 -0
  129. package/pennyfarthing-dist/personas/themes/foundation.yaml +284 -0
  130. package/pennyfarthing-dist/personas/themes/futurama.yaml +313 -0
  131. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +284 -0
  132. package/pennyfarthing-dist/personas/themes/gilligans-island.yaml +365 -0
  133. package/pennyfarthing-dist/personas/themes/gothic-literature.yaml +300 -0
  134. package/pennyfarthing-dist/personas/themes/great-gatsby.yaml +300 -0
  135. package/pennyfarthing-dist/personas/themes/greek-mythology.yaml +326 -0
  136. package/pennyfarthing-dist/personas/themes/hannibal.yaml +294 -0
  137. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +316 -0
  138. package/pennyfarthing-dist/personas/themes/his-dark-materials.yaml +285 -0
  139. package/pennyfarthing-dist/personas/themes/historical-figures.yaml +282 -0
  140. package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +323 -0
  141. package/pennyfarthing-dist/personas/themes/house-md.yaml +313 -0
  142. package/pennyfarthing-dist/personas/themes/imperial-radch.yaml +283 -0
  143. package/pennyfarthing-dist/personas/themes/inspector-morse.yaml +294 -0
  144. package/pennyfarthing-dist/personas/themes/jane-austen.yaml +281 -0
  145. package/pennyfarthing-dist/personas/themes/jazz-legends.yaml +312 -0
  146. package/pennyfarthing-dist/personas/themes/justified.yaml +294 -0
  147. package/pennyfarthing-dist/personas/themes/legion-of-doom.yaml +343 -0
  148. package/pennyfarthing-dist/personas/themes/les-miserables.yaml +293 -0
  149. package/pennyfarthing-dist/personas/themes/lord-of-the-rings.yaml +326 -0
  150. package/pennyfarthing-dist/personas/themes/lovecraft-mythos.yaml +325 -0
  151. package/pennyfarthing-dist/personas/themes/mad-max.yaml +349 -0
  152. package/pennyfarthing-dist/personas/themes/mad-men.yaml +283 -0
  153. package/pennyfarthing-dist/personas/themes/marvel-mcu.yaml +294 -0
  154. package/pennyfarthing-dist/personas/themes/mash.yaml +329 -0
  155. package/pennyfarthing-dist/personas/themes/mass-effect.yaml +283 -0
  156. package/pennyfarthing-dist/personas/themes/military-commanders.yaml +298 -0
  157. package/pennyfarthing-dist/personas/themes/moby-dick.yaml +312 -0
  158. package/pennyfarthing-dist/personas/themes/monty-python.yaml +297 -0
  159. package/pennyfarthing-dist/personas/themes/neuromancer.yaml +294 -0
  160. package/pennyfarthing-dist/personas/themes/norse-mythology.yaml +321 -0
  161. package/pennyfarthing-dist/personas/themes/parks-and-rec.yaml +364 -0
  162. package/pennyfarthing-dist/personas/themes/peaky-blinders.yaml +292 -0
  163. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +344 -0
  164. package/pennyfarthing-dist/personas/themes/renaissance-masters.yaml +312 -0
  165. package/pennyfarthing-dist/personas/themes/rome.yaml +294 -0
  166. package/pennyfarthing-dist/personas/themes/russian-masters.yaml +310 -0
  167. package/pennyfarthing-dist/personas/themes/sandman.yaml +282 -0
  168. package/pennyfarthing-dist/personas/themes/scientific-revolutionaries.yaml +312 -0
  169. package/pennyfarthing-dist/personas/themes/shakespeare.yaml +295 -0
  170. package/pennyfarthing-dist/personas/themes/sherlock-holmes.yaml +283 -0
  171. package/pennyfarthing-dist/personas/themes/snow-crash.yaml +290 -0
  172. package/pennyfarthing-dist/personas/themes/software-pioneers.yaml +294 -0
  173. package/pennyfarthing-dist/personas/themes/star-trek-tng.yaml +358 -0
  174. package/pennyfarthing-dist/personas/themes/star-trek-tos.yaml +327 -0
  175. package/pennyfarthing-dist/personas/themes/star-wars.yaml +297 -0
  176. package/pennyfarthing-dist/personas/themes/succession.yaml +294 -0
  177. package/pennyfarthing-dist/personas/themes/superfriends.yaml +332 -0
  178. package/pennyfarthing-dist/personas/themes/ted-lasso.yaml +359 -0
  179. package/pennyfarthing-dist/personas/themes/the-americans.yaml +294 -0
  180. package/pennyfarthing-dist/personas/themes/the-crown.yaml +294 -0
  181. package/pennyfarthing-dist/personas/themes/the-expanse.yaml +337 -0
  182. package/pennyfarthing-dist/personas/themes/the-good-place.yaml +315 -0
  183. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +342 -0
  184. package/pennyfarthing-dist/personas/themes/the-odyssey.yaml +294 -0
  185. package/pennyfarthing-dist/personas/themes/the-office.yaml +323 -0
  186. package/pennyfarthing-dist/personas/themes/the-simpsons.yaml +300 -0
  187. package/pennyfarthing-dist/personas/themes/the-sopranos.yaml +294 -0
  188. package/pennyfarthing-dist/personas/themes/the-wire.yaml +303 -0
  189. package/pennyfarthing-dist/personas/themes/the-witcher.yaml +294 -0
  190. package/pennyfarthing-dist/personas/themes/twin-peaks.yaml +296 -0
  191. package/pennyfarthing-dist/personas/themes/vorkosigan-saga.yaml +294 -0
  192. package/pennyfarthing-dist/personas/themes/watchmen.yaml +285 -0
  193. package/pennyfarthing-dist/personas/themes/west-wing.yaml +285 -0
  194. package/pennyfarthing-dist/personas/themes/world-explorers.yaml +312 -0
  195. package/pennyfarthing-dist/personas/themes/wwii-leaders.yaml +299 -0
  196. package/pennyfarthing-dist/personas/themes/x-files.yaml +296 -0
  197. package/pennyfarthing-dist/personas/zeitgeist-scores.yaml +1172 -0
  198. package/pennyfarthing-dist/scripts/README.md +87 -0
  199. package/pennyfarthing-dist/scripts/core/README.md +26 -0
  200. package/pennyfarthing-dist/scripts/core/agent-session.sh +383 -0
  201. package/pennyfarthing-dist/scripts/core/check-context.sh +280 -0
  202. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +101 -0
  203. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +95 -0
  204. package/pennyfarthing-dist/scripts/core/prime.sh +30 -0
  205. package/pennyfarthing-dist/scripts/core/run.sh +92 -0
  206. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +21 -0
  207. package/pennyfarthing-dist/scripts/git/README.md +25 -0
  208. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +267 -0
  209. package/pennyfarthing-dist/scripts/git/git-status-all.sh +152 -0
  210. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +91 -0
  211. package/pennyfarthing-dist/scripts/git/release.sh +215 -0
  212. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +494 -0
  213. package/pennyfarthing-dist/scripts/health/drift-detection.sh +162 -0
  214. package/pennyfarthing-dist/scripts/hooks/README.md +32 -0
  215. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +106 -0
  216. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +60 -0
  217. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +65 -0
  218. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +35 -0
  219. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +166 -0
  220. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +107 -0
  221. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +71 -0
  222. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +54 -0
  223. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +20 -0
  224. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +499 -0
  225. package/pennyfarthing-dist/scripts/hooks/session-start.sh +97 -0
  226. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +65 -0
  227. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +94 -0
  228. package/pennyfarthing-dist/scripts/jira/README.md +36 -0
  229. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +101 -0
  230. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +97 -0
  231. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +22 -0
  232. package/pennyfarthing-dist/scripts/jira/jira-lib.sh +464 -0
  233. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +266 -0
  234. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +18 -0
  235. package/pennyfarthing-dist/scripts/jira/jira-sync.sh +16 -0
  236. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +16 -0
  237. package/pennyfarthing-dist/scripts/jira/sync-epic-to-jira.sh +16 -0
  238. package/pennyfarthing-dist/scripts/lib/README.md +29 -0
  239. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +177 -0
  240. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +136 -0
  241. package/pennyfarthing-dist/scripts/lib/common.sh +212 -0
  242. package/pennyfarthing-dist/scripts/lib/file-lock.sh +269 -0
  243. package/pennyfarthing-dist/scripts/lib/find-root.sh +35 -0
  244. package/pennyfarthing-dist/scripts/lib/logging.sh +186 -0
  245. package/pennyfarthing-dist/scripts/lib/retry.sh +76 -0
  246. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +102 -0
  247. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +97 -0
  248. package/pennyfarthing-dist/scripts/misc/README.md +44 -0
  249. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +13 -0
  250. package/pennyfarthing-dist/scripts/misc/add_short_names.py +226 -0
  251. package/pennyfarthing-dist/scripts/misc/backlog.sh +91 -0
  252. package/pennyfarthing-dist/scripts/misc/check-status.sh +247 -0
  253. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +231 -0
  254. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +122 -0
  255. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +74 -0
  256. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +10 -0
  257. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +319 -0
  258. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +141 -0
  259. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +778 -0
  260. package/pennyfarthing-dist/scripts/misc/run-ci.sh +219 -0
  261. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +7 -0
  262. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +319 -0
  263. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +193 -0
  264. package/pennyfarthing-dist/scripts/misc/statusline.sh +259 -0
  265. package/pennyfarthing-dist/scripts/misc/uninstall.sh +270 -0
  266. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +160 -0
  267. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +400 -0
  268. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +54 -0
  269. package/pennyfarthing-dist/scripts/sprint/README.md +29 -0
  270. package/pennyfarthing-dist/scripts/sprint/archive-story.sh +139 -0
  271. package/pennyfarthing-dist/scripts/sprint/available-stories.sh +97 -0
  272. package/pennyfarthing-dist/scripts/sprint/check-story.sh +164 -0
  273. package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +58 -0
  274. package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +69 -0
  275. package/pennyfarthing-dist/scripts/sprint/import-epic-to-future.sh +10 -0
  276. package/pennyfarthing-dist/scripts/sprint/import_epic_to_future.py +270 -0
  277. package/pennyfarthing-dist/scripts/sprint/list-future.sh +151 -0
  278. package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +116 -0
  279. package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +154 -0
  280. package/pennyfarthing-dist/scripts/sprint/sprint-common.sh +421 -0
  281. package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +39 -0
  282. package/pennyfarthing-dist/scripts/sprint/sprint-metrics.sh +241 -0
  283. package/pennyfarthing-dist/scripts/sprint/sprint-status.sh +134 -0
  284. package/pennyfarthing-dist/scripts/story/README.md +23 -0
  285. package/pennyfarthing-dist/scripts/story/create-story.sh +19 -0
  286. package/pennyfarthing-dist/scripts/story/size-story.sh +18 -0
  287. package/pennyfarthing-dist/scripts/story/story-template.sh +18 -0
  288. package/pennyfarthing-dist/scripts/test/README.md +23 -0
  289. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +59 -0
  290. package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +220 -0
  291. package/pennyfarthing-dist/scripts/test/swebench-judge.py +374 -0
  292. package/pennyfarthing-dist/scripts/test/test-cache.sh +165 -0
  293. package/pennyfarthing-dist/scripts/test/test-setup.sh +337 -0
  294. package/pennyfarthing-dist/scripts/tests/check.test.sh +582 -0
  295. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +515 -0
  296. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +599 -0
  297. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +332 -0
  298. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +573 -0
  299. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +859 -0
  300. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +662 -0
  301. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +589 -0
  302. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +105 -0
  303. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +597 -0
  304. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +514 -0
  305. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +517 -0
  306. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +331 -0
  307. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +647 -0
  308. package/pennyfarthing-dist/scripts/theme/README.md +22 -0
  309. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +13 -0
  310. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +402 -0
  311. package/pennyfarthing-dist/scripts/theme/list-themes.sh +73 -0
  312. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +97 -0
  313. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +576 -0
  314. package/pennyfarthing-dist/scripts/workflow/README.md +28 -0
  315. package/pennyfarthing-dist/scripts/workflow/check.py +502 -0
  316. package/pennyfarthing-dist/scripts/workflow/check.sh +24 -0
  317. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +159 -0
  318. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +228 -0
  319. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +61 -0
  320. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +13 -0
  321. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +130 -0
  322. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +40 -0
  323. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +163 -0
  324. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +138 -0
  325. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +256 -0
  326. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +167 -0
  327. package/pennyfarthing-dist/skills/agentic-patterns/SKILL.md +242 -0
  328. package/pennyfarthing-dist/skills/changelog/SKILL.md +367 -0
  329. package/pennyfarthing-dist/skills/code-review/SKILL.md +168 -0
  330. package/pennyfarthing-dist/skills/context-engineering/SKILL.md +274 -0
  331. package/pennyfarthing-dist/skills/cyclist/SKILL.md +88 -0
  332. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +437 -0
  333. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +258 -0
  334. package/pennyfarthing-dist/skills/jira/SKILL.md +484 -0
  335. package/pennyfarthing-dist/skills/judge/SKILL.md +636 -0
  336. package/pennyfarthing-dist/skills/just/SKILL.md +403 -0
  337. package/pennyfarthing-dist/skills/mermaid/SKILL.md +240 -0
  338. package/pennyfarthing-dist/skills/otel/skill.md +223 -0
  339. package/pennyfarthing-dist/skills/permissions/skill.md +172 -0
  340. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +178 -0
  341. package/pennyfarthing-dist/skills/skill-registry.schema.json +107 -0
  342. package/pennyfarthing-dist/skills/skill-registry.yaml +393 -0
  343. package/pennyfarthing-dist/skills/sprint/scripts/archive-story.sh +101 -0
  344. package/pennyfarthing-dist/skills/sprint/scripts/available-stories.sh +97 -0
  345. package/pennyfarthing-dist/skills/sprint/scripts/check-story.sh +164 -0
  346. package/pennyfarthing-dist/skills/sprint/scripts/create-jira-epic.sh +101 -0
  347. package/pennyfarthing-dist/skills/sprint/scripts/new-sprint.sh +116 -0
  348. package/pennyfarthing-dist/skills/sprint/scripts/promote-epic.sh +164 -0
  349. package/pennyfarthing-dist/skills/sprint/scripts/sprint-info.sh +39 -0
  350. package/pennyfarthing-dist/skills/sprint/scripts/sprint-status.sh +147 -0
  351. package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +86 -0
  352. package/pennyfarthing-dist/skills/sprint/skill.md +465 -0
  353. package/pennyfarthing-dist/skills/story/scripts/create-story.sh +159 -0
  354. package/pennyfarthing-dist/skills/story/scripts/size-story.sh +198 -0
  355. package/pennyfarthing-dist/skills/story/scripts/story-template.sh +162 -0
  356. package/pennyfarthing-dist/skills/story/skill.md +219 -0
  357. package/pennyfarthing-dist/skills/systematic-debugging/SKILL.md +390 -0
  358. package/pennyfarthing-dist/skills/testing/SKILL.md +99 -0
  359. package/pennyfarthing-dist/skills/testing/references/troubleshooting.md +124 -0
  360. package/pennyfarthing-dist/skills/theme/skill.md +129 -0
  361. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +174 -0
  362. package/pennyfarthing-dist/skills/workflow/scripts/list-workflows.sh +91 -0
  363. package/pennyfarthing-dist/skills/workflow/scripts/resume-workflow.sh +163 -0
  364. package/pennyfarthing-dist/skills/workflow/scripts/show-workflow.sh +138 -0
  365. package/pennyfarthing-dist/skills/workflow/scripts/start-workflow.sh +273 -0
  366. package/pennyfarthing-dist/skills/workflow/scripts/workflow-status.sh +167 -0
  367. package/pennyfarthing-dist/skills/workflow/skill.md +337 -0
  368. package/pennyfarthing-dist/skills/yq/SKILL.md +264 -0
  369. package/pennyfarthing-dist/templates/LEADERBOARD.schema.yaml +187 -0
  370. package/pennyfarthing-dist/templates/LEADERBOARD.template.md +59 -0
  371. package/pennyfarthing-dist/templates/agent-scopes.yaml.template +276 -0
  372. package/pennyfarthing-dist/templates/pennyfarthing-settings.yaml.template +61 -0
  373. package/pennyfarthing-dist/templates/persona-config.yaml.template +22 -0
  374. package/pennyfarthing-dist/templates/preferences.yaml.template +15 -0
  375. package/pennyfarthing-dist/templates/settings.local.json.template +101 -0
  376. package/pennyfarthing-dist/templates/setup-env.sh.template +18 -0
  377. package/pennyfarthing-dist/templates/shared-context.md.template +70 -0
  378. package/pennyfarthing-dist/templates/sidecar/decisions.md.template +40 -0
  379. package/pennyfarthing-dist/templates/sidecar/gotchas.md.template +37 -0
  380. package/pennyfarthing-dist/templates/sidecar/patterns.md.template +34 -0
  381. package/pennyfarthing-dist/workflows/agent-docs.yaml +70 -0
  382. package/pennyfarthing-dist/workflows/architecture/steps/step-01-initialize.md +101 -0
  383. package/pennyfarthing-dist/workflows/architecture/steps/step-01b-continue.md +93 -0
  384. package/pennyfarthing-dist/workflows/architecture/steps/step-02-context.md +115 -0
  385. package/pennyfarthing-dist/workflows/architecture/steps/step-03-patterns.md +133 -0
  386. package/pennyfarthing-dist/workflows/architecture/steps/step-04-components.md +138 -0
  387. package/pennyfarthing-dist/workflows/architecture/steps/step-05-interfaces.md +133 -0
  388. package/pennyfarthing-dist/workflows/architecture/steps/step-06-risks.md +142 -0
  389. package/pennyfarthing-dist/workflows/architecture/steps/step-07-document.md +160 -0
  390. package/pennyfarthing-dist/workflows/architecture/templates/architecture-decision.md +102 -0
  391. package/pennyfarthing-dist/workflows/architecture.yaml +65 -0
  392. package/pennyfarthing-dist/workflows/bdd.yaml +60 -0
  393. package/pennyfarthing-dist/workflows/brainstorming/brain-methods.csv +62 -0
  394. package/pennyfarthing-dist/workflows/brainstorming/checklist.md +44 -0
  395. package/pennyfarthing-dist/workflows/brainstorming/instructions.md +736 -0
  396. package/pennyfarthing-dist/workflows/brainstorming/workflow.yaml +49 -0
  397. package/pennyfarthing-dist/workflows/code-review/checklist.md +23 -0
  398. package/pennyfarthing-dist/workflows/code-review/instructions.md +234 -0
  399. package/pennyfarthing-dist/workflows/code-review/workflow.yaml +51 -0
  400. package/pennyfarthing-dist/workflows/dev-story/checklist.md +80 -0
  401. package/pennyfarthing-dist/workflows/dev-story/instructions.xml +410 -0
  402. package/pennyfarthing-dist/workflows/dev-story/workflow.yaml +50 -0
  403. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-01-validate-prerequisites.md +256 -0
  404. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-02-design-epics.md +233 -0
  405. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-03-create-stories.md +272 -0
  406. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-04-final-validation.md +153 -0
  407. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +122 -0
  408. package/pennyfarthing-dist/workflows/epics-and-stories/templates/epics-template.md +57 -0
  409. package/pennyfarthing-dist/workflows/epics-and-stories/workflow.yaml +28 -0
  410. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +101 -0
  411. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-02-categorize.md +116 -0
  412. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-03-execute.md +224 -0
  413. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +88 -0
  414. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +79 -0
  415. package/pennyfarthing-dist/workflows/git-cleanup.yaml +59 -0
  416. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-01-document-discovery.md +190 -0
  417. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-02-prd-analysis.md +178 -0
  418. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
  419. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-04-ux-alignment.md +139 -0
  420. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
  421. package/pennyfarthing-dist/workflows/implementation-readiness/steps/step-06-final-assessment.md +133 -0
  422. package/pennyfarthing-dist/workflows/implementation-readiness/templates/readiness-report-template.md +4 -0
  423. package/pennyfarthing-dist/workflows/implementation-readiness/workflow.yaml +40 -0
  424. package/pennyfarthing-dist/workflows/prd/data/domain-complexity.csv +13 -0
  425. package/pennyfarthing-dist/workflows/prd/data/prd-purpose.md +197 -0
  426. package/pennyfarthing-dist/workflows/prd/data/project-types.csv +11 -0
  427. package/pennyfarthing-dist/workflows/prd/steps-c/step-01-init.md +191 -0
  428. package/pennyfarthing-dist/workflows/prd/steps-c/step-01b-continue.md +153 -0
  429. package/pennyfarthing-dist/workflows/prd/steps-c/step-02-discovery.md +224 -0
  430. package/pennyfarthing-dist/workflows/prd/steps-c/step-03-success.md +226 -0
  431. package/pennyfarthing-dist/workflows/prd/steps-c/step-04-journeys.md +213 -0
  432. package/pennyfarthing-dist/workflows/prd/steps-c/step-05-domain.md +207 -0
  433. package/pennyfarthing-dist/workflows/prd/steps-c/step-06-innovation.md +226 -0
  434. package/pennyfarthing-dist/workflows/prd/steps-c/step-07-project-type.md +237 -0
  435. package/pennyfarthing-dist/workflows/prd/steps-c/step-08-scoping.md +228 -0
  436. package/pennyfarthing-dist/workflows/prd/steps-c/step-09-functional.md +231 -0
  437. package/pennyfarthing-dist/workflows/prd/steps-c/step-10-nonfunctional.md +242 -0
  438. package/pennyfarthing-dist/workflows/prd/steps-c/step-11-polish.md +217 -0
  439. package/pennyfarthing-dist/workflows/prd/steps-c/step-12-complete.md +180 -0
  440. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01-discovery.md +247 -0
  441. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
  442. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-02-review.md +249 -0
  443. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-03-edit.md +253 -0
  444. package/pennyfarthing-dist/workflows/prd/steps-e/step-e-04-complete.md +168 -0
  445. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-01-discovery.md +218 -0
  446. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02-format-detection.md +191 -0
  447. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-02b-parity-check.md +209 -0
  448. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-03-density-validation.md +174 -0
  449. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
  450. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-05-measurability-validation.md +228 -0
  451. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-06-traceability-validation.md +217 -0
  452. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
  453. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
  454. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-09-project-type-validation.md +263 -0
  455. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-10-smart-validation.md +209 -0
  456. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
  457. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-12-completeness-validation.md +242 -0
  458. package/pennyfarthing-dist/workflows/prd/steps-v/step-v-13-report-complete.md +232 -0
  459. package/pennyfarthing-dist/workflows/prd/templates/prd-template.md +10 -0
  460. package/pennyfarthing-dist/workflows/prd/workflow.yaml +42 -0
  461. package/pennyfarthing-dist/workflows/product-brief/steps/step-01-init.md +177 -0
  462. package/pennyfarthing-dist/workflows/product-brief/steps/step-01b-continue.md +161 -0
  463. package/pennyfarthing-dist/workflows/product-brief/steps/step-02-vision.md +199 -0
  464. package/pennyfarthing-dist/workflows/product-brief/steps/step-03-users.md +202 -0
  465. package/pennyfarthing-dist/workflows/product-brief/steps/step-04-metrics.md +205 -0
  466. package/pennyfarthing-dist/workflows/product-brief/steps/step-05-scope.md +219 -0
  467. package/pennyfarthing-dist/workflows/product-brief/steps/step-06-complete.md +194 -0
  468. package/pennyfarthing-dist/workflows/product-brief/templates/product-brief.template.md +10 -0
  469. package/pennyfarthing-dist/workflows/product-brief/workflow.yaml +31 -0
  470. package/pennyfarthing-dist/workflows/project-context/project-context-template.md +21 -0
  471. package/pennyfarthing-dist/workflows/project-context/steps/step-01-discover.md +184 -0
  472. package/pennyfarthing-dist/workflows/project-context/steps/step-02-generate.md +318 -0
  473. package/pennyfarthing-dist/workflows/project-context/steps/step-03-complete.md +278 -0
  474. package/pennyfarthing-dist/workflows/project-context/workflow.yaml +27 -0
  475. package/pennyfarthing-dist/workflows/quick-dev/steps/step-01-mode-detection.md +156 -0
  476. package/pennyfarthing-dist/workflows/quick-dev/steps/step-02-context-gathering.md +120 -0
  477. package/pennyfarthing-dist/workflows/quick-dev/steps/step-03-execute.md +113 -0
  478. package/pennyfarthing-dist/workflows/quick-dev/steps/step-04-self-check.md +113 -0
  479. package/pennyfarthing-dist/workflows/quick-dev/steps/step-05-adversarial-review.md +106 -0
  480. package/pennyfarthing-dist/workflows/quick-dev/steps/step-06-resolve-findings.md +140 -0
  481. package/pennyfarthing-dist/workflows/quick-dev/workflow.yaml +27 -0
  482. package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +189 -0
  483. package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +144 -0
  484. package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +128 -0
  485. package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +191 -0
  486. package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +74 -0
  487. package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +27 -0
  488. package/pennyfarthing-dist/workflows/research/steps-domain/step-01-init.md +137 -0
  489. package/pennyfarthing-dist/workflows/research/steps-domain/step-02-domain-analysis.md +229 -0
  490. package/pennyfarthing-dist/workflows/research/steps-domain/step-03-competitive-landscape.md +238 -0
  491. package/pennyfarthing-dist/workflows/research/steps-domain/step-04-regulatory-focus.md +206 -0
  492. package/pennyfarthing-dist/workflows/research/steps-domain/step-05-technical-trends.md +234 -0
  493. package/pennyfarthing-dist/workflows/research/steps-domain/step-06-research-synthesis.md +443 -0
  494. package/pennyfarthing-dist/workflows/research/steps-market/step-01-init.md +182 -0
  495. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-behavior.md +237 -0
  496. package/pennyfarthing-dist/workflows/research/steps-market/step-02-customer-insights.md +200 -0
  497. package/pennyfarthing-dist/workflows/research/steps-market/step-03-customer-pain-points.md +249 -0
  498. package/pennyfarthing-dist/workflows/research/steps-market/step-04-customer-decisions.md +259 -0
  499. package/pennyfarthing-dist/workflows/research/steps-market/step-05-competitive-analysis.md +177 -0
  500. package/pennyfarthing-dist/workflows/research/steps-market/step-06-research-completion.md +475 -0
  501. package/pennyfarthing-dist/workflows/research/steps-technical/step-01-init.md +137 -0
  502. package/pennyfarthing-dist/workflows/research/steps-technical/step-02-technical-overview.md +239 -0
  503. package/pennyfarthing-dist/workflows/research/steps-technical/step-03-integration-patterns.md +248 -0
  504. package/pennyfarthing-dist/workflows/research/steps-technical/step-04-architectural-patterns.md +202 -0
  505. package/pennyfarthing-dist/workflows/research/steps-technical/step-05-implementation-research.md +239 -0
  506. package/pennyfarthing-dist/workflows/research/steps-technical/step-06-research-synthesis.md +486 -0
  507. package/pennyfarthing-dist/workflows/research/templates/research.template.md +29 -0
  508. package/pennyfarthing-dist/workflows/research/workflow.yaml +45 -0
  509. package/pennyfarthing-dist/workflows/retrospective/checklist.md +31 -0
  510. package/pennyfarthing-dist/workflows/retrospective/instructions.md +1443 -0
  511. package/pennyfarthing-dist/workflows/retrospective/workflow.yaml +50 -0
  512. package/pennyfarthing-dist/workflows/sprint-planning/checklist.md +33 -0
  513. package/pennyfarthing-dist/workflows/sprint-planning/sprint-status-template.yaml +55 -0
  514. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-01-parse-epic-files.md +54 -0
  515. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-02-build-sprint-status.md +44 -0
  516. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-03-status-detection.md +64 -0
  517. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-04-generate-status-file.md +73 -0
  518. package/pennyfarthing-dist/workflows/sprint-planning/steps/step-05-validate-and-report.md +56 -0
  519. package/pennyfarthing-dist/workflows/sprint-planning/workflow.yaml +34 -0
  520. package/pennyfarthing-dist/workflows/tdd.yaml +50 -0
  521. package/pennyfarthing-dist/workflows/trivial.yaml +40 -0
  522. package/pennyfarthing-dist/workflows/ux-design/steps/step-01-init.md +135 -0
  523. package/pennyfarthing-dist/workflows/ux-design/steps/step-01b-continue.md +127 -0
  524. package/pennyfarthing-dist/workflows/ux-design/steps/step-02-discovery.md +190 -0
  525. package/pennyfarthing-dist/workflows/ux-design/steps/step-03-core-experience.md +216 -0
  526. package/pennyfarthing-dist/workflows/ux-design/steps/step-04-emotional-response.md +219 -0
  527. package/pennyfarthing-dist/workflows/ux-design/steps/step-05-inspiration.md +234 -0
  528. package/pennyfarthing-dist/workflows/ux-design/steps/step-06-design-system.md +252 -0
  529. package/pennyfarthing-dist/workflows/ux-design/steps/step-07-defining-experience.md +254 -0
  530. package/pennyfarthing-dist/workflows/ux-design/steps/step-08-visual-foundation.md +224 -0
  531. package/pennyfarthing-dist/workflows/ux-design/steps/step-09-design-directions.md +224 -0
  532. package/pennyfarthing-dist/workflows/ux-design/steps/step-10-user-journeys.md +241 -0
  533. package/pennyfarthing-dist/workflows/ux-design/steps/step-11-component-strategy.md +248 -0
  534. package/pennyfarthing-dist/workflows/ux-design/steps/step-12-ux-patterns.md +237 -0
  535. package/pennyfarthing-dist/workflows/ux-design/steps/step-13-responsive-accessibility.md +264 -0
  536. package/pennyfarthing-dist/workflows/ux-design/steps/step-14-complete.md +228 -0
  537. package/pennyfarthing-dist/workflows/ux-design/ux-design-template.md +13 -0
  538. package/pennyfarthing-dist/workflows/ux-design/workflow.yaml +41 -0
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env zsh
2
+ # Common utility functions for Pennyfarthing scripts
3
+ # Source this file: source "${SCRIPT_DIR}/lib/common.sh"
4
+ #
5
+ # Provides:
6
+ # - Output helpers: success, info, warn, error
7
+ # - Dry-run check: dry_run_check
8
+ # - JQL escaping: escape_for_jql
9
+ # - Jira JSON helpers: get_issue_json, get_jira_field
10
+
11
+ #############################################
12
+ # Output Helpers
13
+ #############################################
14
+
15
+ # Color codes
16
+ _RED='\033[31m'
17
+ _GREEN='\033[32m'
18
+ _YELLOW='\033[33m'
19
+ _BLUE='\033[34m'
20
+ _NC='\033[0m' # No Color
21
+
22
+ # success MESSAGE
23
+ # Print a success message in green (to stderr for visibility)
24
+ success() {
25
+ echo -e "${_GREEN}[OK]${_NC} $1" >&2
26
+ }
27
+
28
+ # info MESSAGE
29
+ # Print an info message in blue (to stderr for visibility)
30
+ info() {
31
+ echo -e "${_BLUE}[INFO]${_NC} $1" >&2
32
+ }
33
+
34
+ # warn MESSAGE
35
+ # Print a warning message in yellow (to stderr for visibility)
36
+ warn() {
37
+ echo -e "${_YELLOW}[WARN]${_NC} $1" >&2
38
+ }
39
+
40
+ # error MESSAGE
41
+ # Print an error message in red (to stderr, does NOT exit)
42
+ error() {
43
+ echo -e "${_RED}[ERROR]${_NC} $1" >&2
44
+ }
45
+
46
+ #############################################
47
+ # Dry-Run Support
48
+ #############################################
49
+
50
+ # dry_run_check ACTION
51
+ # Check if DRY_RUN is enabled and print a warning
52
+ # Returns 0 if dry-run is active (caller should skip the action)
53
+ # Returns 1 if dry-run is NOT active (caller should proceed)
54
+ #
55
+ # Usage:
56
+ # if dry_run_check "create epic: $summary"; then
57
+ # echo "DRYRUN-EPIC-001"
58
+ # return
59
+ # fi
60
+ # # ... actual implementation
61
+ #
62
+ dry_run_check() {
63
+ local action="$1"
64
+ if [ "$DRY_RUN" = true ]; then
65
+ warn "[DRY-RUN] Would ${action}"
66
+ return 0
67
+ fi
68
+ return 1
69
+ }
70
+
71
+ #############################################
72
+ # JQL Helpers
73
+ #############################################
74
+
75
+ # escape_for_jql STRING
76
+ # Escape a string for use in JQL queries
77
+ # Escapes double quotes and other special characters
78
+ #
79
+ # Usage:
80
+ # local escaped=$(escape_for_jql "$summary")
81
+ # jira issue list --jql "summary~'${escaped}'"
82
+ #
83
+ escape_for_jql() {
84
+ echo "$1" | sed 's/"/\\"/g'
85
+ }
86
+
87
+ #############################################
88
+ # Jira JSON Helpers
89
+ #############################################
90
+
91
+ # get_issue_json ISSUE_KEY
92
+ # Fetch Jira issue as JSON with error handling
93
+ # Returns empty object {} if issue not found
94
+ # Sets exit code 1 if fetch failed
95
+ #
96
+ # Usage:
97
+ # local json=$(get_issue_json "PROJ-123")
98
+ # if [ -z "$json" ] || [ "$json" = "{}" ]; then
99
+ # warn "Could not fetch issue"
100
+ # fi
101
+ #
102
+ get_issue_json() {
103
+ local key="$1"
104
+ local json
105
+ json=$(jira issue view "$key" --raw 2>/dev/null)
106
+ if [ -z "$json" ]; then
107
+ echo "{}"
108
+ return 1
109
+ fi
110
+ echo "$json"
111
+ }
112
+
113
+ # get_jira_field JSON FIELD_PATH [DEFAULT]
114
+ # Extract a field from Jira issue JSON using jq
115
+ #
116
+ # Arguments:
117
+ # JSON - The JSON string to parse
118
+ # FIELD_PATH - jq path expression (e.g., '.fields.summary')
119
+ # DEFAULT - Optional default value if field is null/empty
120
+ #
121
+ # Usage:
122
+ # local summary=$(get_jira_field "$json" '.fields.summary')
123
+ # local points=$(get_jira_field "$json" '.fields.customfield_10031' '0')
124
+ #
125
+ get_jira_field() {
126
+ local json="$1"
127
+ local field_path="$2"
128
+ local default="${3:-}"
129
+
130
+ if [ -n "$default" ]; then
131
+ echo "$json" | jq -r "${field_path} // \"${default}\""
132
+ else
133
+ echo "$json" | jq -r "${field_path} // empty"
134
+ fi
135
+ }
136
+
137
+ #############################################
138
+ # Dependency Checks
139
+ #############################################
140
+
141
+ # check_dependencies
142
+ # Check for common required tools
143
+ # Can be extended with optional checks
144
+ check_dependencies() {
145
+ local missing=()
146
+
147
+ # Check for jq (required for JSON parsing)
148
+ if ! command -v jq &> /dev/null; then
149
+ missing+=("jq")
150
+ error "jq not found - install with: brew install jq"
151
+ fi
152
+
153
+ if [ ${#missing[@]} -gt 0 ]; then
154
+ return 1
155
+ fi
156
+ return 0
157
+ }
158
+
159
+ #############################################
160
+ # Python Execution
161
+ #############################################
162
+
163
+ # get_python
164
+ # Find the best Python interpreter (venv preferred, fallback to system)
165
+ # Sets PYTHON_CMD variable
166
+ #
167
+ # Priority:
168
+ # 1. PROJECT_ROOT/.venv/bin/python (project venv)
169
+ # 2. python3 (system)
170
+ # 3. python (legacy fallback)
171
+ #
172
+ # Usage:
173
+ # get_python
174
+ # $PYTHON_CMD -m pennyfarthing_scripts.jira view MSSCI-12345
175
+ #
176
+ get_python() {
177
+ # Find project root if not set
178
+ if [[ -z "${PROJECT_ROOT:-}" ]]; then
179
+ local d="$PWD"
180
+ while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do
181
+ d="$(dirname "$d")"
182
+ done
183
+ PROJECT_ROOT="$d"
184
+ fi
185
+
186
+ # Check for project venv first
187
+ if [[ -x "${PROJECT_ROOT}/.venv/bin/python" ]]; then
188
+ PYTHON_CMD="${PROJECT_ROOT}/.venv/bin/python"
189
+ elif command -v python3 &> /dev/null; then
190
+ PYTHON_CMD="python3"
191
+ elif command -v python &> /dev/null; then
192
+ PYTHON_CMD="python"
193
+ else
194
+ error "Python not found. Install Python 3.11+ or create .venv"
195
+ return 1
196
+ fi
197
+ }
198
+
199
+ # run_python_module MODULE [ARGS...]
200
+ # Run a pennyfarthing_scripts Python module with proper venv handling
201
+ #
202
+ # Usage:
203
+ # run_python_module jira view MSSCI-12345
204
+ # run_python_module sprint status
205
+ # run_python_module story size 3
206
+ #
207
+ run_python_module() {
208
+ get_python || return 1
209
+ local module="$1"
210
+ shift
211
+ exec $PYTHON_CMD -m "pennyfarthing_scripts.${module}" "$@"
212
+ }
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env zsh
2
+ # File locking utilities for session file concurrency protection
3
+ # Dev: Fanny Price - "We have all a better guide in ourselves."
4
+
5
+ # Default timeout in seconds
6
+ DEFAULT_LOCK_TIMEOUT=10
7
+
8
+ # Stale lock threshold in seconds (5 minutes)
9
+ STALE_LOCK_THRESHOLD=300
10
+
11
+ # _get_lock_dir
12
+ # Internal function to get lock directory (evaluated at call time)
13
+ _get_lock_dir() {
14
+ echo "${PROJECT_ROOT:-.}/.session/.locks"
15
+ }
16
+
17
+ # _get_lock_file FILEPATH
18
+ # Internal function to derive lock file path from target file
19
+ #
20
+ # Arguments:
21
+ # FILEPATH - Path to the file to lock
22
+ #
23
+ # Returns:
24
+ # Outputs the lock file path
25
+ #
26
+ _get_lock_file() {
27
+ local filepath="$1"
28
+ local filename
29
+ local lock_dir
30
+ filename=$(basename "$filepath")
31
+ lock_dir=$(_get_lock_dir)
32
+ echo "${lock_dir}/.${filename}.lock"
33
+ }
34
+
35
+ # _check_stale_lock LOCKFILE
36
+ # Internal function to check and remove stale locks
37
+ #
38
+ # Arguments:
39
+ # LOCKFILE - Path to lock file to check
40
+ #
41
+ # Returns:
42
+ # 0 if lock was stale and removed, 1 if lock is valid
43
+ #
44
+ _check_stale_lock() {
45
+ local lockfile="$1"
46
+
47
+ if [[ ! -f "$lockfile" ]]; then
48
+ return 1
49
+ fi
50
+
51
+ # Get lock file age in seconds
52
+ local now lock_mtime age
53
+ now=$(date +%s)
54
+
55
+ # macOS stat vs Linux stat differ
56
+ if [[ "$(uname)" == "Darwin" ]]; then
57
+ lock_mtime=$(stat -f %m "$lockfile" 2>/dev/null || echo 0)
58
+ else
59
+ lock_mtime=$(stat -c %Y "$lockfile" 2>/dev/null || echo 0)
60
+ fi
61
+
62
+ age=$((now - lock_mtime))
63
+
64
+ if ((age > STALE_LOCK_THRESHOLD)); then
65
+ # Log warning about stale lock
66
+ echo "[WARN] Removing stale lock: $lockfile (age: ${age}s)" >&2
67
+ rm -f "$lockfile"
68
+ return 0
69
+ fi
70
+
71
+ return 1
72
+ }
73
+
74
+ # lock_acquire FILEPATH [LOCK_TYPE] [TIMEOUT]
75
+ # Acquire a lock on a file
76
+ #
77
+ # Arguments:
78
+ # FILEPATH - Path to the file to lock
79
+ # LOCK_TYPE - "exclusive" (default) or "shared"
80
+ # TIMEOUT - Timeout in seconds (default: 10)
81
+ #
82
+ # Returns:
83
+ # 0 on success, 1 on timeout/failure
84
+ #
85
+ # Example:
86
+ # lock_acquire ".session/checkpoints.log"
87
+ # lock_acquire ".session/agent-logs.jsonl" "exclusive" 5
88
+ #
89
+ lock_acquire() {
90
+ local filepath="$1"
91
+ local lock_type="${2:-exclusive}"
92
+ local timeout="${3:-$DEFAULT_LOCK_TIMEOUT}"
93
+ local lockfile
94
+ local flock_opts
95
+ local start_time
96
+ local elapsed
97
+
98
+ lockfile=$(_get_lock_file "$filepath")
99
+ local lock_dir
100
+ lock_dir=$(_get_lock_dir)
101
+
102
+ # Ensure lock directory exists
103
+ mkdir -p "$lock_dir"
104
+
105
+ # Check for stale lock first (ignore return value)
106
+ _check_stale_lock "$lockfile" || true
107
+
108
+ # Set flock options based on lock type
109
+ case "$lock_type" in
110
+ shared)
111
+ flock_opts="-s"
112
+ ;;
113
+ exclusive|*)
114
+ flock_opts="-x"
115
+ ;;
116
+ esac
117
+
118
+ # Try to acquire lock with timeout
119
+ start_time=$(date +%s)
120
+ local my_pid="$$"
121
+
122
+ while true; do
123
+ # Try to create lock file atomically using ln (atomic on POSIX)
124
+ # Create a temp file with our PID, then try to hard-link it
125
+ local temp_lock="${lockfile}.${my_pid}"
126
+ echo "$my_pid" > "$temp_lock"
127
+
128
+ if ln "$temp_lock" "$lockfile" 2>/dev/null; then
129
+ rm -f "$temp_lock"
130
+ return 0
131
+ fi
132
+ rm -f "$temp_lock"
133
+
134
+ # Check if we've exceeded timeout
135
+ elapsed=$(( $(date +%s) - start_time ))
136
+ if ((elapsed >= timeout)); then
137
+ echo "[WARN] Lock timeout on $filepath after ${timeout}s" >&2
138
+ return 1
139
+ fi
140
+
141
+ # Check for stale lock
142
+ if _check_stale_lock "$lockfile" 2>/dev/null; then
143
+ continue # Try again now that stale lock is removed
144
+ fi
145
+
146
+ # Wait a bit before retrying (100ms)
147
+ sleep 0.1
148
+ done
149
+ }
150
+
151
+ # lock_release FILEPATH
152
+ # Release a lock on a file
153
+ #
154
+ # Arguments:
155
+ # FILEPATH - Path to the file to unlock
156
+ #
157
+ # Returns:
158
+ # 0 on success
159
+ #
160
+ # Example:
161
+ # lock_release ".session/checkpoints.log"
162
+ #
163
+ lock_release() {
164
+ local filepath="$1"
165
+ local lockfile
166
+
167
+ lockfile=$(_get_lock_file "$filepath")
168
+
169
+ # Only remove if we own the lock (PID matches)
170
+ if [[ -f "$lockfile" ]]; then
171
+ local lock_pid
172
+ lock_pid=$(cat "$lockfile" 2>/dev/null || echo "")
173
+ if [[ "$lock_pid" == "$$" ]]; then
174
+ rm -f "$lockfile"
175
+ fi
176
+ fi
177
+
178
+ return 0
179
+ }
180
+
181
+ # with_lock FILEPATH LOCK_TYPE COMMAND...
182
+ # Execute a command while holding a lock
183
+ #
184
+ # Arguments:
185
+ # FILEPATH - Path to the file to lock
186
+ # LOCK_TYPE - "exclusive" or "shared"
187
+ # COMMAND - Command and arguments to execute
188
+ #
189
+ # Returns:
190
+ # Exit code of the command, or 1 if lock failed
191
+ #
192
+ # Example:
193
+ # with_lock ".session/checkpoints.log" "exclusive" echo "data" >> file
194
+ # with_lock ".session/data.json" "shared" cat file
195
+ #
196
+ with_lock() {
197
+ local filepath="$1"
198
+ local lock_type="$2"
199
+ shift 2
200
+
201
+ if ! lock_acquire "$filepath" "$lock_type"; then
202
+ return 1
203
+ fi
204
+
205
+ # Execute command and capture exit code
206
+ local exit_code
207
+ "$@"
208
+ exit_code=$?
209
+
210
+ lock_release "$filepath"
211
+
212
+ return $exit_code
213
+ }
214
+
215
+ # lock_status FILEPATH
216
+ # Check if a file is currently locked
217
+ #
218
+ # Arguments:
219
+ # FILEPATH - Path to the file to check
220
+ #
221
+ # Returns:
222
+ # 0 if locked, 1 if not locked
223
+ # Outputs lock holder PID if locked
224
+ #
225
+ # Example:
226
+ # if lock_status ".session/checkpoints.log"; then
227
+ # echo "File is locked"
228
+ # fi
229
+ #
230
+ lock_status() {
231
+ local filepath="$1"
232
+ local lockfile
233
+
234
+ lockfile=$(_get_lock_file "$filepath")
235
+
236
+ if [[ -f "$lockfile" ]]; then
237
+ # Check for stale lock
238
+ if _check_stale_lock "$lockfile"; then
239
+ return 1
240
+ fi
241
+ cat "$lockfile"
242
+ return 0
243
+ fi
244
+
245
+ return 1
246
+ }
247
+
248
+ # lock_cleanup
249
+ # Remove all stale locks in the lock directory
250
+ #
251
+ # Example:
252
+ # lock_cleanup
253
+ #
254
+ lock_cleanup() {
255
+ local lock_dir
256
+ lock_dir=$(_get_lock_dir)
257
+
258
+ if [[ ! -d "$lock_dir" ]]; then
259
+ return 0
260
+ fi
261
+
262
+ local lockfile
263
+ for lockfile in "$lock_dir"/.*.lock; do
264
+ [[ -f "$lockfile" ]] || continue
265
+ _check_stale_lock "$lockfile"
266
+ done
267
+ }
268
+
269
+ # Functions available when sourced
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env zsh
2
+ # Shared utility: Find project root by .pennyfarthing/ marker
3
+ #
4
+ # DEPRECATED: Scripts invoked via run.sh already have PROJECT_ROOT set.
5
+ # This file is kept for backwards compatibility with scripts that may be
6
+ # run directly (not via run.sh).
7
+ #
8
+ # When run.sh executes a script, it sets PROJECT_ROOT before exec'ing,
9
+ # so sourcing this file is a no-op (line 12 skips if already set).
10
+ #
11
+ # For new scripts: Just assume PROJECT_ROOT is set by the caller (run.sh).
12
+
13
+ # Skip if PROJECT_ROOT is already set (e.g., by run.sh or CLAUDE_PROJECT_DIR)
14
+ if [ -z "${PROJECT_ROOT:-}" ]; then
15
+ # Prefer SCRIPT_DIR (stable, set by caller) over PWD (may not be in project)
16
+ if [ -n "${SCRIPT_DIR:-}" ]; then
17
+ _find_root_dir="$SCRIPT_DIR"
18
+ else
19
+ _find_root_dir="$PWD"
20
+ fi
21
+
22
+ while [[ ! -d "$_find_root_dir/.pennyfarthing" ]] && [[ "$_find_root_dir" != "/" ]]; do
23
+ _find_root_dir="$(dirname "$_find_root_dir")"
24
+ done
25
+
26
+ if [[ -d "$_find_root_dir/.pennyfarthing" ]]; then
27
+ PROJECT_ROOT="$_find_root_dir"
28
+ else
29
+ echo "Error: Could not find project root (no .pennyfarthing/ directory found)" >&2
30
+ exit 1
31
+ fi
32
+ unset _find_root_dir
33
+ fi
34
+
35
+ export PROJECT_ROOT
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env zsh
2
+ # Structured JSON logging utilities for agent workflows
3
+ # Dev: Fanny Price - "Let other pens dwell on guilt and misery."
4
+
5
+ # Source file locking utilities
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=file-lock.sh
8
+ source "${SCRIPT_DIR}/file-lock.sh" 2>/dev/null || true
9
+
10
+ # Log file location (evaluated dynamically)
11
+ _get_log_file() {
12
+ echo "${PROJECT_ROOT:-.}/.session/agent-logs.jsonl"
13
+ }
14
+
15
+ # _log LEVEL MESSAGE [EXTRA_FIELDS]
16
+ # Internal function to write structured log entry
17
+ #
18
+ # Arguments:
19
+ # LEVEL - Log level (INFO, WARN, ERROR)
20
+ # MESSAGE - Log message
21
+ # EXTRA_FIELDS - Optional extra JSON fields (must be valid JSON object contents)
22
+ #
23
+ _log() {
24
+ local level="$1"
25
+ local message="$2"
26
+ local extra="${3:-}"
27
+ local timestamp
28
+ local agent
29
+ local session
30
+ local log_file
31
+
32
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
33
+ agent="${AGENT_NAME:-unknown}"
34
+ session="${SESSION_ID:-}"
35
+ log_file=$(_get_log_file)
36
+
37
+ # Ensure directory exists
38
+ mkdir -p "$(dirname "$log_file")"
39
+
40
+ # Escape message for JSON (handle quotes and newlines)
41
+ message=$(printf '%s' "$message" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' ' ')
42
+
43
+ # Build JSON object
44
+ local json="{\"timestamp\":\"${timestamp}\",\"level\":\"${level}\",\"agent\":\"${agent}\",\"message\":\"${message}\""
45
+
46
+ # Add session_id if present
47
+ if [[ -n "$session" ]]; then
48
+ json="${json},\"session_id\":\"${session}\""
49
+ fi
50
+
51
+ # Add extra fields if provided
52
+ if [[ -n "$extra" ]]; then
53
+ json="${json},${extra}"
54
+ fi
55
+
56
+ json="${json}}"
57
+
58
+ # Acquire lock, write to log file, release lock
59
+ if lock_acquire "$log_file" "exclusive" 5 2>/dev/null; then
60
+ echo "$json" >> "$log_file"
61
+ lock_release "$log_file"
62
+ else
63
+ # Fallback: write without lock (better than failing)
64
+ echo "$json" >> "$log_file"
65
+ fi
66
+
67
+ # Also output to stderr for visibility (with color)
68
+ case "$level" in
69
+ INFO) echo -e "\033[32m[INFO]\033[0m $message" >&2 ;;
70
+ WARN) echo -e "\033[33m[WARN]\033[0m $message" >&2 ;;
71
+ ERROR) echo -e "\033[31m[ERROR]\033[0m $message" >&2 ;;
72
+ esac
73
+ }
74
+
75
+ # log_info MESSAGE [EXTRA_FIELDS]
76
+ # Log an informational message
77
+ #
78
+ # Arguments:
79
+ # MESSAGE - Log message
80
+ # EXTRA_FIELDS - Optional extra JSON fields
81
+ #
82
+ # Example:
83
+ # log_info "Starting workflow"
84
+ # log_info "File processed" '"file":"src/main.go","lines":42'
85
+ #
86
+ log_info() {
87
+ _log "INFO" "$1" "${2:-}"
88
+ }
89
+
90
+ # log_warn MESSAGE [EXTRA_FIELDS]
91
+ # Log a warning message
92
+ #
93
+ # Arguments:
94
+ # MESSAGE - Log message
95
+ # EXTRA_FIELDS - Optional extra JSON fields
96
+ #
97
+ # Example:
98
+ # log_warn "Context usage high"
99
+ # log_warn "Retry needed" '"attempt":2,"max":3'
100
+ #
101
+ log_warn() {
102
+ _log "WARN" "$1" "${2:-}"
103
+ }
104
+
105
+ # log_error MESSAGE [EXTRA_FIELDS]
106
+ # Log an error message
107
+ #
108
+ # Arguments:
109
+ # MESSAGE - Log message
110
+ # EXTRA_FIELDS - Optional extra JSON fields
111
+ #
112
+ # Example:
113
+ # log_error "Command failed"
114
+ # log_error "Test failure" '"test":"test_auth","exit_code":1'
115
+ #
116
+ log_error() {
117
+ _log "ERROR" "$1" "${2:-}"
118
+ }
119
+
120
+ # log_list [N]
121
+ # List recent log entries
122
+ #
123
+ # Arguments:
124
+ # N - Number of entries to show (default: 20)
125
+ #
126
+ # Example:
127
+ # log_list
128
+ # log_list 50
129
+ #
130
+ log_list() {
131
+ local count=${1:-20}
132
+ local log_file
133
+ log_file=$(_get_log_file)
134
+
135
+ if [[ -f "$log_file" ]]; then
136
+ tail -n "$count" "$log_file"
137
+ fi
138
+ }
139
+
140
+ # log_clear
141
+ # Remove all log entries
142
+ #
143
+ # Example:
144
+ # log_clear
145
+ #
146
+ log_clear() {
147
+ local log_file
148
+ log_file=$(_get_log_file)
149
+ rm -f "$log_file"
150
+ }
151
+
152
+ # log_rotate [MAX_LINES]
153
+ # Rotate log file to prevent unbounded growth
154
+ #
155
+ # Arguments:
156
+ # MAX_LINES - Maximum lines to keep (default: 1000)
157
+ #
158
+ # Example:
159
+ # log_rotate
160
+ # log_rotate 500
161
+ #
162
+ log_rotate() {
163
+ local max_lines=${1:-1000}
164
+ local log_file
165
+ log_file=$(_get_log_file)
166
+
167
+ if [[ ! -f "$log_file" ]]; then
168
+ return 0
169
+ fi
170
+
171
+ # Acquire exclusive lock for rotation
172
+ if lock_acquire "$log_file" "exclusive" 5 2>/dev/null; then
173
+ local current_lines
174
+ current_lines=$(wc -l < "$log_file")
175
+
176
+ if ((current_lines > max_lines)); then
177
+ local temp_file
178
+ temp_file=$(mktemp)
179
+ tail -n "$max_lines" "$log_file" > "$temp_file"
180
+ mv "$temp_file" "$log_file"
181
+ fi
182
+ lock_release "$log_file"
183
+ fi
184
+ }
185
+
186
+ # Functions available when sourced