@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,76 @@
1
+ #!/usr/bin/env zsh
2
+ # Retry utilities with exponential backoff
3
+ # Dev: Fanny Price - "We have all a better guide in ourselves, if we would attend to it."
4
+
5
+ # retry_with_backoff MAX_ATTEMPTS INITIAL_DELAY MAX_DELAY COMMAND...
6
+ # Retry a command with exponential backoff
7
+ #
8
+ # Arguments:
9
+ # MAX_ATTEMPTS - Maximum number of attempts (default: 3)
10
+ # INITIAL_DELAY - Initial delay in seconds (default: 1)
11
+ # MAX_DELAY - Maximum delay cap in seconds (default: 30)
12
+ # COMMAND... - Command to execute
13
+ #
14
+ # Returns:
15
+ # 0 if command succeeds within attempts
16
+ # 1 if all attempts exhausted
17
+ #
18
+ # Example:
19
+ # retry_with_backoff 3 1 10 curl -s https://api.example.com/health
20
+ #
21
+ retry_with_backoff() {
22
+ local max_attempts=${1:-3}
23
+ local delay=${2:-1}
24
+ local max_delay=${3:-30}
25
+ shift 3
26
+
27
+ local attempt=1
28
+ while true; do
29
+ # Try the command
30
+ if "$@"; then
31
+ return 0
32
+ fi
33
+
34
+ # Check if we've exhausted attempts
35
+ if ((attempt >= max_attempts)); then
36
+ return 1
37
+ fi
38
+
39
+ # Wait before retry
40
+ sleep "$delay"
41
+
42
+ # Exponential backoff with cap
43
+ delay=$((delay * 2))
44
+ if ((delay > max_delay)); then
45
+ delay=$max_delay
46
+ fi
47
+
48
+ attempt=$((attempt + 1))
49
+ done
50
+ }
51
+
52
+ # command_with_fallback PRIMARY_CMD FALLBACK_CMD
53
+ # Execute primary command, fall back to alternative if it fails
54
+ #
55
+ # Arguments:
56
+ # PRIMARY_CMD - Primary command to try (as string)
57
+ # FALLBACK_CMD - Fallback command if primary fails (as string)
58
+ #
59
+ # Returns:
60
+ # Exit code of whichever command succeeds (or fallback's exit code)
61
+ #
62
+ # Example:
63
+ # command_with_fallback "git pull --ff-only" "git pull --no-rebase"
64
+ #
65
+ command_with_fallback() {
66
+ local primary_cmd="$1"
67
+ local fallback_cmd="$2"
68
+
69
+ if eval "$primary_cmd"; then
70
+ return 0
71
+ else
72
+ eval "$fallback_cmd"
73
+ fi
74
+ }
75
+
76
+ # Functions available when sourced - no export needed in zsh
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Migration Script: Consolidate quote into catchphrases (MSSCI-12478)
4
+ *
5
+ * For each theme YAML:
6
+ * 1. For each agent: if quote exists and isn't in catchphrases, add it
7
+ * 2. Remove the quote field from all agents
8
+ */
9
+
10
+ import { readFileSync, writeFileSync, readdirSync } from 'node:fs';
11
+ import { join, dirname } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = dirname(__filename);
16
+
17
+ const THEMES_DIR = join(__dirname, '..', '..', 'personas', 'themes');
18
+
19
+ function migrateThemeFile(filePath) {
20
+ let content = readFileSync(filePath, 'utf-8');
21
+ const lines = content.split('\n');
22
+ const result = [];
23
+
24
+ let i = 0;
25
+ while (i < lines.length) {
26
+ const line = lines[i];
27
+ const trimmed = line.trimEnd();
28
+
29
+ // Check for quote: at 4-space indent (agent level)
30
+ if (/^ quote:/.test(trimmed)) {
31
+ // Extract the quote value
32
+ const quoteMatch = trimmed.match(/^ quote:\s*["']?(.+?)["']?$/);
33
+ if (quoteMatch) {
34
+ const quoteValue = quoteMatch[1];
35
+
36
+ // Look ahead for catchphrases section
37
+ let catchphrasesIndex = -1;
38
+ let catchphrases = [];
39
+
40
+ for (let j = i + 1; j < lines.length; j++) {
41
+ const checkLine = lines[j];
42
+ // Stop if we hit the next agent (2-space indent with colon) or end of agents
43
+ if (/^ \w+:/.test(checkLine) && !/^ /.test(checkLine)) break;
44
+ if (/^agents:/.test(checkLine) || /^theme:/.test(checkLine)) break;
45
+
46
+ if (/^ catchphrases:/.test(checkLine)) {
47
+ catchphrasesIndex = j;
48
+ // Collect existing catchphrases
49
+ for (let k = j + 1; k < lines.length; k++) {
50
+ const catchLine = lines[k];
51
+ if (/^ - /.test(catchLine)) {
52
+ const catchValue = catchLine.replace(/^ - ["']?(.+?)["']?$/, '$1');
53
+ catchphrases.push(catchValue);
54
+ } else if (!/^\s*$/.test(catchLine) && !/^ /.test(catchLine)) {
55
+ break;
56
+ }
57
+ }
58
+ break;
59
+ }
60
+ }
61
+
62
+ // Check if quote is already in catchphrases
63
+ const quoteInCatchphrases = catchphrases.some(c => c === quoteValue);
64
+
65
+ if (!quoteInCatchphrases && catchphrasesIndex === -1) {
66
+ // No catchphrases section - this shouldn't happen based on exploration
67
+ // but handle it anyway by skipping quote (tests expect catchphrases to exist)
68
+ console.log(` Warning: No catchphrases found for agent with quote in ${filePath}`);
69
+ }
70
+
71
+ // Skip the quote line (don't add to result)
72
+ i++;
73
+ continue;
74
+ }
75
+ }
76
+
77
+ result.push(line);
78
+ i++;
79
+ }
80
+
81
+ const newContent = result.join('\n');
82
+ if (newContent !== content) {
83
+ writeFileSync(filePath, newContent);
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+
89
+ // Main
90
+ const files = readdirSync(THEMES_DIR).filter(f => f.endsWith('.yaml'));
91
+ console.log(`Migrating ${files.length} theme files...`);
92
+
93
+ let modified = 0;
94
+ for (const file of files) {
95
+ const filePath = join(THEMES_DIR, file);
96
+ if (migrateThemeFile(filePath)) {
97
+ modified++;
98
+ console.log(` Migrated: ${file}`);
99
+ }
100
+ }
101
+
102
+ console.log(`\nDone. Modified ${modified}/${files.length} files.`);
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+ # sidecar-health.sh - Check sidecar files for bloat and staleness
3
+ #
4
+ # Usage: sidecar-health.sh [--fix]
5
+ # --fix Offer to archive bloated files
6
+ #
7
+ # Thresholds:
8
+ # gotchas.md: 50 lines max
9
+ # patterns.md: 50 lines max
10
+ # decisions.md: 40 lines max
11
+
12
+ set -euo pipefail
13
+
14
+ # Find project root
15
+ if [[ -z "${PROJECT_ROOT:-}" ]]; then
16
+ d="$PWD"
17
+ while [[ ! -d "$d/.pennyfarthing" ]] && [[ "$d" != "/" ]]; do
18
+ d="$(dirname "$d")"
19
+ done
20
+ PROJECT_ROOT="$d"
21
+ fi
22
+
23
+ SIDECAR_DIR="$PROJECT_ROOT/.pennyfarthing/sidecars"
24
+ FIX_MODE="${1:-}"
25
+
26
+ # Thresholds
27
+ GOTCHAS_MAX=50
28
+ PATTERNS_MAX=50
29
+ DECISIONS_MAX=40
30
+
31
+ # Colors
32
+ RED='\033[0;31m'
33
+ YELLOW='\033[1;33m'
34
+ GREEN='\033[0;32m'
35
+ NC='\033[0m' # No Color
36
+
37
+ echo "Sidecar Health Check"
38
+ echo "===================="
39
+ echo ""
40
+
41
+ issues_found=0
42
+
43
+ check_file() {
44
+ local file="$1"
45
+ local max_lines="$2"
46
+ local agent=$(basename "$(dirname "$file")")
47
+ local filename=$(basename "$file")
48
+
49
+ if [[ ! -f "$file" ]]; then
50
+ return
51
+ fi
52
+
53
+ local lines=$(wc -l < "$file" | tr -d ' ')
54
+
55
+ if [[ $lines -gt $max_lines ]]; then
56
+ echo -e "${RED}BLOATED${NC}: $agent/$filename ($lines lines, max $max_lines)"
57
+ issues_found=$((issues_found + 1))
58
+
59
+ if [[ "$FIX_MODE" == "--fix" ]]; then
60
+ local archive_dir="$PROJECT_ROOT/.pennyfarthing/sidecars/.archive"
61
+ local timestamp=$(date +%Y%m%d)
62
+ mkdir -p "$archive_dir"
63
+
64
+ echo " → Archiving to .archive/${agent}-${filename%.md}-${timestamp}.md"
65
+ cp "$file" "$archive_dir/${agent}-${filename%.md}-${timestamp}.md"
66
+ echo " → Original preserved. Manually prune $file to <$max_lines lines."
67
+ fi
68
+ elif [[ $lines -gt $((max_lines * 80 / 100)) ]]; then
69
+ echo -e "${YELLOW}WARNING${NC}: $agent/$filename ($lines lines, approaching $max_lines limit)"
70
+ else
71
+ echo -e "${GREEN}OK${NC}: $agent/$filename ($lines lines)"
72
+ fi
73
+ }
74
+
75
+ # Check all agent sidecars
76
+ for agent_dir in "$SIDECAR_DIR"/*/; do
77
+ if [[ -d "$agent_dir" ]]; then
78
+ agent=$(basename "$agent_dir")
79
+ [[ "$agent" == ".archive" ]] && continue
80
+
81
+ check_file "$agent_dir/gotchas.md" $GOTCHAS_MAX
82
+ check_file "$agent_dir/patterns.md" $PATTERNS_MAX
83
+ check_file "$agent_dir/decisions.md" $DECISIONS_MAX
84
+ fi
85
+ done
86
+
87
+ echo ""
88
+ if [[ $issues_found -gt 0 ]]; then
89
+ echo "Found $issues_found bloated file(s)."
90
+ if [[ "$FIX_MODE" != "--fix" ]]; then
91
+ echo "Run with --fix to archive and prepare for pruning."
92
+ fi
93
+ exit 1
94
+ else
95
+ echo "All sidecar files within limits."
96
+ exit 0
97
+ fi
@@ -0,0 +1,44 @@
1
+ # Miscellaneous Scripts
2
+
3
+ Uncategorized utilities and one-off scripts.
4
+
5
+ ## Scripts
6
+
7
+ | Script | Purpose |
8
+ |--------|---------|
9
+ | `deploy.sh` | Deployment script |
10
+ | `doctor-dogfood.sh` | Health check for dogfooding setup |
11
+ | `run-ci.sh` | Run CI locally |
12
+ | `statusline.sh` | Status line configuration |
13
+ | `uninstall.sh` | Uninstall Pennyfarthing from project |
14
+ | `backlog.sh` | Backlog operations |
15
+ | `repo-utils.sh` | Multi-repo utilities |
16
+ | `repo-scan.sh` | Repository scanner |
17
+ | `add-short-names.mjs` | Add short names to themes |
18
+ | `migrate-bmad-workflow.mjs` | BMAD workflow migration |
19
+ | `migrate-bmad-workflow.sh` | BMAD migration wrapper |
20
+ | `find-related-work.sh` | Find related work items |
21
+ | `check-status.sh` | Status checking utilities |
22
+ | `session-cleanup.sh` | Clean up old sessions |
23
+ | `generate-skill-docs.sh` | Generate skill documentation |
24
+ | `log-skill-usage.sh` | Log skill invocations |
25
+ | `skill-usage-report.sh` | Generate skill usage reports |
26
+ | `run-timestamp.sh` | Timestamp utility |
27
+ | `validate-subagent-frontmatter.sh` | Validate subagent YAML frontmatter |
28
+
29
+ ## Usage
30
+
31
+ ```bash
32
+ .pennyfarthing/scripts/core/run.sh misc/doctor-dogfood.sh
33
+ .pennyfarthing/scripts/core/run.sh misc/run-ci.sh
34
+ ```
35
+
36
+ ## Ownership
37
+
38
+ - **Primary users:** Various
39
+ - **Maintained by:** Core Pennyfarthing team
40
+
41
+ ## Note
42
+
43
+ Scripts here may be candidates for moving to more specific categories
44
+ as the codebase evolves.
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ # add-short-names.sh - Pre-generate shortName field for theme characters
3
+ #
4
+ # Usage:
5
+ # add-short-names.sh # Dry run - show what would change
6
+ # add-short-names.sh --write # Actually write changes
7
+ # add-short-names.sh --theme discworld # Only process one theme
8
+
9
+ set -euo pipefail
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+
13
+ exec python3 "$SCRIPT_DIR/add_short_names.py" "$@"
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ add_short_names.py - Pre-generate shortName field for theme characters
4
+
5
+ Finds the shortest unique identifier that distinguishes each character.
6
+
7
+ Usage:
8
+ python add_short_names.py # Dry run - show what would change
9
+ python add_short_names.py --write # Actually write changes
10
+ python add_short_names.py --theme discworld # Only process one theme
11
+ """
12
+
13
+ import argparse
14
+ import re
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ try:
19
+ import yaml
20
+ except ImportError:
21
+ print("Error: PyYAML required. Install with: pip install pyyaml", file=sys.stderr)
22
+ sys.exit(1)
23
+
24
+
25
+ def find_project_root() -> Path:
26
+ """Find project root by looking for .pennyfarthing directory."""
27
+ current = Path.cwd()
28
+ while current != current.parent:
29
+ if (current / ".pennyfarthing").is_dir():
30
+ return current
31
+ current = current.parent
32
+ return Path.cwd()
33
+
34
+
35
+ # Common titles/prefixes to strip for comparison
36
+ SKIP_PREFIXES = {
37
+ 'the', 'dr.', 'dr', 'captain', 'admiral', 'colonel', 'lieutenant', 'commander',
38
+ 'president', 'lord', 'lady', 'sir', 'professor', 'inspector', 'sergeant',
39
+ 'mr.', 'mr', 'mrs.', 'mrs', 'miss', 'ms.', 'ms', 'chief', 'major', 'general',
40
+ 'king', 'queen', 'prince', 'princess', 'duke', 'earl', 'count', 'baron',
41
+ 'first', 'grand', 'arch', 'high',
42
+ 'uncle', 'aunt', 'brother', 'sister', 'father', 'mother', 'friar',
43
+ 'avatar', 'agent', 'detective', 'officer', 'private', 'corporal',
44
+ 'chancellor', 'ambassador', 'senator', 'governor', 'minister',
45
+ 'master', 'young', 'old', 'elder', 'reverend', 'bishop', 'cardinal'
46
+ }
47
+
48
+ # Words that make poor short names on their own
49
+ POOR_SHORT_NAMES = {
50
+ 'big', 'little', 'old', 'young', 'true', 'false', 'good', 'bad',
51
+ 'thought', 'ministry', 'situation', 'room', 'place', 'house',
52
+ 'superintendent', 'commander', 'speaker', 'council',
53
+ 'mode', 'narrator', 'chronicler',
54
+ 'h.m.', 'j.f.', 'a.w.', 'e.b.', 'l.'
55
+ }
56
+
57
+ # Names that should use the full form (iconic two-word names)
58
+ USE_FULL_NAME = {'big brother', 'sun tzu'}
59
+
60
+
61
+ def extract_nickname(name: str) -> str | None:
62
+ """Extract quoted nickname from character name if present."""
63
+ match = re.search(r'["\']([^"\']+)["\']', name)
64
+ if match:
65
+ nickname = match.group(1).strip()
66
+ if nickname and ' ' not in nickname:
67
+ return nickname
68
+ return None
69
+
70
+
71
+ def clean_name(name: str) -> str:
72
+ """Clean character name by removing parenthetical annotations and slash alternatives."""
73
+ cleaned = re.sub(r'\s*\([^)]+\)\s*', ' ', name).strip()
74
+ cleaned = re.sub(r'\b\w+/(\w+)\s', r'\1 ', cleaned)
75
+ cleaned = re.sub(r'\s*["\'][^"\']+["\']\s*', ' ', cleaned).strip()
76
+ cleaned = re.sub(r'\s+', ' ', cleaned).strip()
77
+ return cleaned
78
+
79
+
80
+ def tokenize(name: str) -> list[str]:
81
+ """Tokenize a name into meaningful parts."""
82
+ cleaned = clean_name(name)
83
+ words = [w for w in cleaned.split() if w]
84
+
85
+ filtered = [
86
+ w for w in words
87
+ if w.lower() not in SKIP_PREFIXES
88
+ and not re.match(r'^[A-Z]\.$', w)
89
+ and not re.match(r'^[IVXLCDM]+$', w)
90
+ ]
91
+
92
+ return filtered if filtered else words
93
+
94
+
95
+ def compute_short_names(agents: dict) -> dict[str, str]:
96
+ """Compute display name map for all characters in a theme."""
97
+ characters = [
98
+ a['character'] for a in agents.values()
99
+ if a and a.get('character')
100
+ ]
101
+
102
+ def is_unique(candidate: str, except_for: str) -> bool:
103
+ candidate_lower = candidate.lower()
104
+ for char in characters:
105
+ if char == except_for:
106
+ continue
107
+ tokens = tokenize(char)
108
+ if any(t.lower() == candidate_lower for t in tokens):
109
+ return False
110
+ return True
111
+
112
+ def is_good_short_name(candidate: str) -> bool:
113
+ return candidate.lower() not in POOR_SHORT_NAMES and len(candidate) > 1
114
+
115
+ def find_short_name(full_name: str) -> str:
116
+ cleaned = clean_name(full_name)
117
+
118
+ if cleaned.lower() in USE_FULL_NAME:
119
+ return cleaned
120
+
121
+ nickname = extract_nickname(full_name)
122
+ if nickname and is_good_short_name(nickname):
123
+ return nickname
124
+
125
+ tokens = tokenize(full_name)
126
+
127
+ if not tokens:
128
+ return cleaned
129
+
130
+ if len(tokens) == 1:
131
+ return tokens[0]
132
+
133
+ # Strategy 1: First token (if good and unique)
134
+ if is_good_short_name(tokens[0]) and is_unique(tokens[0], full_name):
135
+ return tokens[0]
136
+
137
+ # Strategy 2: Last token (surname, if good and unique)
138
+ last_token = tokens[-1]
139
+ if is_good_short_name(last_token) and is_unique(last_token, full_name):
140
+ return last_token
141
+
142
+ # Strategy 3: First + Last
143
+ if len(tokens) >= 2:
144
+ first_last = f"{tokens[0]} {last_token}"
145
+ if is_unique(first_last, full_name):
146
+ return first_last
147
+
148
+ return clean_name(full_name)
149
+
150
+ return {char: find_short_name(char) for char in characters}
151
+
152
+
153
+ def process_theme(filepath: Path, dry_run: bool = True) -> dict:
154
+ """Process a single theme file."""
155
+ content = filepath.read_text()
156
+ theme = yaml.safe_load(content)
157
+
158
+ if not theme or 'agents' not in theme:
159
+ print(f" Skipping {filepath.name} - no agents found")
160
+ return {'changes': 0, 'filename': filepath.name}
161
+
162
+ short_names = compute_short_names(theme['agents'])
163
+ changes = 0
164
+
165
+ for role, agent in theme['agents'].items():
166
+ if not agent or 'character' not in agent:
167
+ continue
168
+
169
+ short_name = short_names.get(agent['character'])
170
+ existing = agent.get('shortName')
171
+
172
+ if short_name and short_name != existing:
173
+ if dry_run:
174
+ existing_note = f' (was: "{existing}")' if existing else ''
175
+ print(f' {role}: "{agent["character"]}" -> "{short_name}"{existing_note}')
176
+ agent['shortName'] = short_name
177
+ changes += 1
178
+
179
+ if not dry_run and changes > 0:
180
+ with open(filepath, 'w') as f:
181
+ yaml.dump(theme, f, default_flow_style=False, allow_unicode=True, width=1000)
182
+ print(f" Wrote {changes} changes to {filepath.name}")
183
+
184
+ return {'changes': changes, 'filename': filepath.name}
185
+
186
+
187
+ def main() -> int:
188
+ parser = argparse.ArgumentParser(
189
+ description="Pre-generate shortName field for theme characters"
190
+ )
191
+ parser.add_argument('--write', action='store_true',
192
+ help='Actually write changes (default: dry run)')
193
+ parser.add_argument('--theme', type=str,
194
+ help='Only process one theme')
195
+ args = parser.parse_args()
196
+
197
+ dry_run = not args.write
198
+
199
+ project_root = find_project_root()
200
+ themes_dir = project_root / 'pennyfarthing-dist' / 'personas' / 'themes'
201
+
202
+ print('DRY RUN - No files will be modified\n' if dry_run else 'WRITING CHANGES\n')
203
+
204
+ files = sorted(themes_dir.glob('*.yaml'))
205
+ if args.theme:
206
+ theme_file = f"{args.theme}.yaml" if not args.theme.endswith('.yaml') else args.theme
207
+ files = [f for f in files if f.name == theme_file]
208
+
209
+ total_changes = 0
210
+ for file in files:
211
+ print(f"\n{file.name}:")
212
+ result = process_theme(file, dry_run)
213
+ total_changes += result['changes']
214
+ if result['changes'] == 0:
215
+ print(' (no changes needed)')
216
+
217
+ print(f"\n{'=' * 50}")
218
+ print(f"Total: {total_changes} changes across {len(files)} themes")
219
+ if dry_run and total_changes > 0:
220
+ print("\nRun with --write to apply changes")
221
+
222
+ return 0
223
+
224
+
225
+ if __name__ == "__main__":
226
+ sys.exit(main())
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env zsh
2
+ # backlog.sh - Display backlog stories in a formatted table
3
+ # Usage: backlog.sh
4
+ # Reads sprint/current-sprint.yaml and outputs backlog stories
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="${0:A:h}"
9
+ PROJECT_ROOT="${SCRIPT_DIR}/../.."
10
+
11
+ # Find project root by looking for .pennyfarthing directory
12
+ find_project_root() {
13
+ local dir="$PWD"
14
+ while [[ "$dir" != "/" ]]; do
15
+ if [[ -d "$dir/.pennyfarthing" ]]; then
16
+ echo "$dir"
17
+ return 0
18
+ fi
19
+ dir="$(dirname "$dir")"
20
+ done
21
+ echo "$PWD"
22
+ }
23
+
24
+ PROJECT_ROOT="$(find_project_root)"
25
+ SPRINT_FILE="$PROJECT_ROOT/sprint/current-sprint.yaml"
26
+
27
+ if [[ ! -f "$SPRINT_FILE" ]]; then
28
+ echo "Error: sprint/current-sprint.yaml not found" >&2
29
+ exit 1
30
+ fi
31
+
32
+ # Parse YAML and extract backlog stories
33
+ # Output format: | Story | Title | Pts | Epic |
34
+
35
+ echo "| Story | Title | Pts | Epic |"
36
+ echo "|-------|-------|-----|------|"
37
+
38
+ # Use yq if available, otherwise fall back to grep/awk
39
+ if command -v yq &>/dev/null; then
40
+ yq eval '
41
+ .epics[] |
42
+ .id as $epic_id |
43
+ .stories[]? |
44
+ select(.status == "backlog") |
45
+ "| " + .id + " | " + .title + " | " + (.points | tostring) + " | " + $epic_id + " |"
46
+ ' "$SPRINT_FILE"
47
+ else
48
+ # Fallback: grep-based extraction
49
+ current_epic=""
50
+ in_stories=false
51
+
52
+ while IFS= read -r line; do
53
+ # Detect epic id
54
+ if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*id:[[:space:]]*(MSSCI-[0-9]+) ]]; then
55
+ current_epic="${match[1]}"
56
+ in_stories=false
57
+ fi
58
+
59
+ # Detect stories section
60
+ if [[ "$line" =~ ^[[:space:]]*stories: ]]; then
61
+ in_stories=true
62
+ fi
63
+
64
+ # Detect story with backlog status (look ahead)
65
+ if [[ "$in_stories" == true && "$line" =~ ^[[:space:]]*-[[:space:]]*id:[[:space:]]*(MSSCI-[0-9]+) ]]; then
66
+ story_id="${match[1]}"
67
+ story_title=""
68
+ story_points=""
69
+ story_status=""
70
+
71
+ # Read next lines for this story
72
+ while IFS= read -r detail; do
73
+ [[ "$detail" =~ ^[[:space:]]*-[[:space:]]*id: ]] && break
74
+ [[ "$detail" =~ ^[[:space:]]*title:[[:space:]]*[\"\']*(.+)[\"\']*$ ]] && story_title="${match[1]}"
75
+ [[ "$detail" =~ ^[[:space:]]*points:[[:space:]]*([0-9]+) ]] && story_points="${match[1]}"
76
+ [[ "$detail" =~ ^[[:space:]]*status:[[:space:]]*(.+) ]] && story_status="${match[1]}"
77
+
78
+ # If we have all fields and status is backlog, print and break
79
+ if [[ -n "$story_title" && -n "$story_points" && "$story_status" == "backlog" ]]; then
80
+ echo "| $story_id | $story_title | $story_points | $current_epic |"
81
+ break
82
+ fi
83
+
84
+ # If status is not backlog, skip this story
85
+ if [[ -n "$story_status" && "$story_status" != "backlog" ]]; then
86
+ break
87
+ fi
88
+ done
89
+ fi
90
+ done < "$SPRINT_FILE"
91
+ fi