@pennyfarthing/core 11.1.0 → 11.2.0

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 (263) hide show
  1. package/README.md +8 -8
  2. package/package.json +16 -14
  3. package/packages/core/dist/cli/utils/constants.d.ts +1 -1
  4. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  5. package/packages/core/dist/cli/utils/constants.js +2 -1
  6. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  7. package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
  8. package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
  9. package/packages/core/dist/consultation/dialogue-manager.js +334 -0
  10. package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
  11. package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
  12. package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
  13. package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
  14. package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
  15. package/packages/core/dist/server/api/git.d.ts +13 -1
  16. package/packages/core/dist/server/api/git.d.ts.map +1 -1
  17. package/packages/core/dist/server/api/git.js +53 -34
  18. package/packages/core/dist/server/api/git.js.map +1 -1
  19. package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
  20. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  21. package/packages/core/dist/server/otlp-receiver.js +185 -24
  22. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  23. package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
  24. package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
  25. package/packages/core/dist/server/otlp-receiver.test.js +446 -0
  26. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
  27. package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
  28. package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
  29. package/packages/core/dist/shared/portrait-resolver.js +27 -0
  30. package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
  31. package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
  32. package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
  33. package/packages/core/dist/shared/skill-search.test.js +2 -2
  34. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
  35. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
  36. package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
  37. package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
  38. package/pennyfarthing-dist/agents/dev.md +1 -1
  39. package/pennyfarthing-dist/agents/reviewer.md +1 -1
  40. package/pennyfarthing-dist/agents/sm-setup.md +1 -1
  41. package/pennyfarthing-dist/agents/sm.md +2 -2
  42. package/pennyfarthing-dist/agents/tea.md +1 -1
  43. package/pennyfarthing-dist/agents/testing-runner.md +2 -1
  44. package/pennyfarthing-dist/commands/pf-chore.md +2 -2
  45. package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
  46. package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
  47. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
  48. package/pennyfarthing-dist/guides/bikerack.md +3 -3
  49. package/pennyfarthing-dist/guides/hooks.md +1 -1
  50. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  51. package/pennyfarthing-dist/guides/xml-tags.md +2 -2
  52. package/pennyfarthing-dist/scripts/README.md +1 -1
  53. package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
  54. package/pennyfarthing-dist/scripts/core/check-context.sh +1 -1
  55. package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
  56. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  57. package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
  58. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  59. package/pennyfarthing-dist/scripts/git/README.md +24 -14
  60. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
  61. package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
  62. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
  63. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  64. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
  65. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  66. package/pennyfarthing-dist/scripts/hooks/README.md +1 -1
  67. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
  68. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  69. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  70. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  71. package/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh +0 -0
  72. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
  73. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
  74. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
  75. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  76. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
  77. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  78. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  79. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  80. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  81. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  82. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  83. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
  84. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
  85. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
  86. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  87. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
  88. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  89. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  90. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  91. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  92. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  93. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  94. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  95. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  96. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  97. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  98. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  99. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  100. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  101. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  102. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  103. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  104. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  105. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  106. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
  107. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  108. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  109. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  110. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  111. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  112. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  113. package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
  114. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  115. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
  116. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  117. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
  118. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  119. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  120. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  121. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  122. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  123. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  124. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
  125. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  126. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  127. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  128. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  129. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  130. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
  131. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  132. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  133. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  134. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  135. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  136. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
  137. package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
  138. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  139. package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
  140. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
  141. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
  142. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  143. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
  144. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
  145. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
  146. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
  147. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
  148. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
  149. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
  150. package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
  151. package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
  152. package/pennyfarthing-dist/skills/pf-story/scripts/create-story.sh +0 -0
  153. package/pennyfarthing-dist/skills/pf-story/scripts/size-story.sh +0 -0
  154. package/pennyfarthing-dist/skills/pf-story/scripts/story-template.sh +0 -0
  155. package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
  156. package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
  157. package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
  158. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
  159. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
  160. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
  161. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
  162. package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
  163. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
  164. package/pennyfarthing_scripts/CLAUDE.md +26 -4
  165. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  166. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  167. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/bc/cli.py +3 -5
  171. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  172. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  183. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
  185. package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
  186. package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
  187. package/pennyfarthing_scripts/bikerack/cli.py +10 -11
  188. package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
  189. package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
  190. package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
  191. package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
  192. package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
  193. package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
  194. package/pennyfarthing_scripts/bikerack/tui.py +336 -30
  195. package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
  196. package/pennyfarthing_scripts/cli.py +37 -65
  197. package/pennyfarthing_scripts/consultation/__init__.py +1 -0
  198. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/consultation/cli.py +149 -0
  201. package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
  202. package/pennyfarthing_scripts/context.py +3 -3
  203. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/git/__init__.py +12 -1
  206. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
  212. package/pennyfarthing_scripts/git/create_branches.py +3 -4
  213. package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
  214. package/pennyfarthing_scripts/git/repos.py +196 -0
  215. package/pennyfarthing_scripts/git/status_all.py +27 -11
  216. package/pennyfarthing_scripts/git/worktree.py +302 -0
  217. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing_scripts/git_group/cli.py +143 -40
  220. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  221. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  222. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  223. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
  225. package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
  226. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  227. package/pennyfarthing_scripts/hooks.py +3 -17
  228. package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
  229. package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
  230. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/prime/heatmap.py +655 -0
  232. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  233. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/session_start_hook.py +1 -1
  235. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/sprint/loader.py +15 -1
  237. package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
  238. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  239. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  240. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  241. package/pennyfarthing_scripts/tests/test_bikerack.py +51 -51
  242. package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
  243. package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
  244. package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
  245. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
  247. package/pennyfarthing_scripts/validate/cli.py +17 -5
  248. package/pennyfarthing_scripts/workflow/__init__.py +40 -0
  249. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/workflow/cli.py +1099 -0
  255. package/pennyfarthing_scripts/workflow/helpers.py +241 -0
  256. package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
  257. package/pennyfarthing_scripts/workflow/state.py +112 -0
  258. package/scripts/README.md +41 -0
  259. package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
  260. package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
  261. package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
  262. package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
  263. package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
File without changes
File without changes
File without changes
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env zsh
2
+ #
3
+ # generate-tandem-portraits.sh — Generate per-theme tandem cyclist branding images
4
+ #
5
+ # Processes cyclist_tandem.png source into medium (200x200) and large (300x300)
6
+ # versions for each theme's portrait directory.
7
+ #
8
+ # Usage: ./generate-tandem-portraits.sh [--source PATH] [--portraits-dir PATH]
9
+
10
+ set -euo pipefail
11
+
12
+ SCRIPT_DIR="${0:A:h}"
13
+ # Source image lives alongside portraits in pennyfarthing-dist
14
+ DIST_DIR="${SCRIPT_DIR}/../.."
15
+ SOURCE_IMAGE="${DIST_DIR}/personas/portraits/cyclist-tandem-source.png"
16
+ PORTRAITS_DIR=""
17
+
18
+ # Parse arguments
19
+ while [[ $# -gt 0 ]]; do
20
+ case "$1" in
21
+ --source) SOURCE_IMAGE="$2"; shift 2 ;;
22
+ --portraits-dir) PORTRAITS_DIR="$2"; shift 2 ;;
23
+ *) echo "Unknown option: $1"; exit 1 ;;
24
+ esac
25
+ done
26
+
27
+ # Auto-detect portraits directory if not provided
28
+ if [[ -z "$PORTRAITS_DIR" ]]; then
29
+ PORTRAITS_DIR="${DIST_DIR}/personas/portraits"
30
+ fi
31
+
32
+ # Resolve to absolute path
33
+ PORTRAITS_DIR="${PORTRAITS_DIR:A}"
34
+
35
+ if [[ ! -f "$SOURCE_IMAGE" ]]; then
36
+ echo "Error: Source image not found: $SOURCE_IMAGE"
37
+ exit 1
38
+ fi
39
+
40
+ if [[ ! -d "$PORTRAITS_DIR" ]]; then
41
+ echo "Error: Portraits directory not found: $PORTRAITS_DIR"
42
+ exit 1
43
+ fi
44
+
45
+ # Verify ImageMagick is available
46
+ if ! command -v magick &>/dev/null; then
47
+ echo "Error: ImageMagick (magick) not found in PATH"
48
+ exit 1
49
+ fi
50
+
51
+ echo "Source: $SOURCE_IMAGE"
52
+ echo "Portraits: $PORTRAITS_DIR"
53
+ echo ""
54
+
55
+ generated=0
56
+ skipped=0
57
+
58
+ for theme_dir in "$PORTRAITS_DIR"/*/; do
59
+ theme_name="$(basename "$theme_dir")"
60
+
61
+ for size_name size_px in medium 200 large 300; do
62
+ size_dir="${theme_dir}${size_name}"
63
+ output="${size_dir}/cyclist-tandem.png"
64
+
65
+ # Create size directory if it doesn't exist
66
+ mkdir -p "$size_dir"
67
+
68
+ # Generate resized tandem portrait
69
+ magick "$SOURCE_IMAGE" -resize "${size_px}x${size_px}" -strip "$output"
70
+ generated=$((generated + 1))
71
+ done
72
+ done
73
+
74
+ echo ""
75
+ echo "Generated: $generated tandem portraits"
76
+ echo "Done."
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,222 +1,5 @@
1
1
  #!/bin/bash
2
- # Fix session file phase tracking when handoffs didn't update properly
3
- # Usage: fix-session-phase.sh <story-id> <target-phase> [--dry-run]
4
- #
5
- # Example: fix-session-phase.sh 56-1 review
6
- # fix-session-phase.sh MSSCI-12190 approved --dry-run
7
- #
8
- # This script detects the current phase, validates the target phase is reachable,
9
- # and updates the session file's Workflow Tracking section:
10
- # - Updates **Phase:** field to target phase
11
- # - Adds missing rows to Phase History table
12
- # - Adds missing rows to Handoff History table
13
- #
14
- # Valid phases for TDD workflow: setup → red → green → review → approved → finish
15
- # Valid phases for trivial workflow: setup → implement → review → approved → finish
16
-
17
- set -euo pipefail
18
-
19
- STORY_ID="${1:-}"
20
- TARGET_PHASE="${2:-}"
21
- DRY_RUN=false
22
-
23
- # Parse options
24
- for arg in "$@"; do
25
- case $arg in
26
- --dry-run)
27
- DRY_RUN=true
28
- ;;
29
- esac
30
- done
31
-
32
- if [[ -z "$STORY_ID" ]] || [[ -z "$TARGET_PHASE" ]]; then
33
- echo "Usage: fix-session-phase.sh <story-id> <target-phase> [--dry-run]"
34
- echo ""
35
- echo "Arguments:"
36
- echo " story-id Story ID (e.g., 56-1 or MSSCI-12190)"
37
- echo " target-phase Target phase to set (e.g., review, approved, finish)"
38
- echo ""
39
- echo "Options:"
40
- echo " --dry-run Show what would be done without executing"
41
- echo ""
42
- echo "Examples:"
43
- echo " fix-session-phase.sh 56-1 review # Update to review phase"
44
- echo " fix-session-phase.sh 56-1 approved # Update to approved phase"
45
- echo " fix-session-phase.sh 56-1 finish --dry-run # Preview finish update"
46
- exit 1
47
- fi
48
-
49
- # Find project root
50
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
51
-
52
- # Try multiple session file naming patterns
53
- SESSION_FILE=""
54
- STORY_ID_LOWER=$(echo "$STORY_ID" | tr '[:upper:]' '[:lower:]')
55
- for pattern in "${STORY_ID}-session.md" "${STORY_ID_LOWER}-session.md"; do
56
- if [[ -f "$PROJECT_ROOT/.session/$pattern" ]]; then
57
- SESSION_FILE="$PROJECT_ROOT/.session/$pattern"
58
- break
59
- fi
60
- done
61
-
62
- # Also try without the epic prefix (e.g., MSSCI-12190 might be in 56-1-session.md)
63
- if [[ -z "$SESSION_FILE" ]]; then
64
- # Search for session files containing this story ID
65
- found=$(grep -l "Jira:.*$STORY_ID\|ID:.*$STORY_ID" "$PROJECT_ROOT/.session/"*-session.md 2>/dev/null | head -1 || echo "")
66
- if [[ -n "$found" ]]; then
67
- SESSION_FILE="$found"
68
- fi
69
- fi
70
-
71
- if [[ -z "$SESSION_FILE" ]] || [[ ! -f "$SESSION_FILE" ]]; then
72
- echo "Error: Session file not found for story $STORY_ID"
73
- echo "Searched in: $PROJECT_ROOT/.session/"
74
- exit 1
75
- fi
76
-
77
- echo "Session file: $SESSION_FILE"
78
-
79
- # Extract current state
80
- CURRENT_PHASE=$(grep -E '^\*\*Phase:\*\*' "$SESSION_FILE" | sed 's/\*\*Phase:\*\* //' | tr -d ' ' || echo "unknown")
81
- WORKFLOW=$(grep -E '^\*\*Workflow:\*\*' "$SESSION_FILE" | head -1 | sed 's/\*\*Workflow:\*\* //' | tr -d ' ' || echo "tdd")
82
- PHASE_STARTED=$(grep -E '^\*\*Phase Started:\*\*' "$SESSION_FILE" | sed 's/\*\*Phase Started:\*\* //' | tr -d ' ' || echo "")
83
-
84
- echo "Current phase: $CURRENT_PHASE"
85
- echo "Target phase: $TARGET_PHASE"
86
- echo "Workflow: $WORKFLOW"
87
-
88
- # Define valid phase sequences
89
- case "$WORKFLOW" in
90
- tdd)
91
- PHASES=("setup" "red" "green" "review" "approved" "finish")
92
- AGENTS=("sm" "tea" "dev" "reviewer" "sm" "sm")
93
- GATES=("manual" "tests_fail" "tests_pass" "approval" "complete" "")
94
- ;;
95
- trivial)
96
- PHASES=("setup" "implement" "review" "approved" "finish")
97
- AGENTS=("sm" "dev" "reviewer" "sm" "sm")
98
- GATES=("manual" "tests_pass" "approval" "complete" "")
99
- ;;
100
- *)
101
- echo "Warning: Unknown workflow '$WORKFLOW', assuming TDD"
102
- PHASES=("setup" "red" "green" "review" "approved" "finish")
103
- AGENTS=("sm" "tea" "dev" "reviewer" "sm" "sm")
104
- GATES=("manual" "tests_fail" "tests_pass" "approval" "complete" "")
105
- ;;
106
- esac
107
-
108
- # Find indices
109
- CURRENT_IDX=-1
110
- TARGET_IDX=-1
111
- for i in "${!PHASES[@]}"; do
112
- if [[ "${PHASES[$i]}" == "$CURRENT_PHASE" ]]; then
113
- CURRENT_IDX=$i
114
- fi
115
- if [[ "${PHASES[$i]}" == "$TARGET_PHASE" ]]; then
116
- TARGET_IDX=$i
117
- fi
118
- done
119
-
120
- if [[ $CURRENT_IDX -eq -1 ]]; then
121
- echo "Error: Current phase '$CURRENT_PHASE' not found in $WORKFLOW workflow"
122
- echo "Valid phases: ${PHASES[*]}"
123
- exit 1
124
- fi
125
-
126
- if [[ $TARGET_IDX -eq -1 ]]; then
127
- echo "Error: Target phase '$TARGET_PHASE' not found in $WORKFLOW workflow"
128
- echo "Valid phases: ${PHASES[*]}"
129
- exit 1
130
- fi
131
-
132
- if [[ $TARGET_IDX -le $CURRENT_IDX ]]; then
133
- echo "Error: Target phase '$TARGET_PHASE' is not ahead of current phase '$CURRENT_PHASE'"
134
- echo "Phase sequence: ${PHASES[*]}"
135
- exit 1
136
- fi
137
-
138
- # Calculate what transitions are needed
139
- echo ""
140
- echo "Transitions needed:"
141
- NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
142
- TRANSITIONS=()
143
-
144
- for ((i=CURRENT_IDX; i<TARGET_IDX; i++)); do
145
- FROM_PHASE="${PHASES[$i]}"
146
- TO_PHASE="${PHASES[$((i+1))]}"
147
- FROM_AGENT="${AGENTS[$i]}"
148
- TO_AGENT="${AGENTS[$((i+1))]}"
149
- GATE="${GATES[$((i+1))]}"
150
-
151
- echo " $FROM_PHASE ($FROM_AGENT) → $TO_PHASE ($TO_AGENT) [gate: $GATE]"
152
- TRANSITIONS+=("$FROM_PHASE|$TO_PHASE|$FROM_AGENT|$TO_AGENT|$GATE")
153
- done
154
-
155
- if [[ "$DRY_RUN" == "true" ]]; then
156
- echo ""
157
- echo "[DRY RUN] Would update session file with:"
158
- echo " - **Phase:** $TARGET_PHASE"
159
- echo " - **Phase Started:** $NOW"
160
- echo " - Phase History: close out $CURRENT_PHASE, add intermediate phases"
161
- echo " - Handoff History: add ${#TRANSITIONS[@]} handoff(s)"
162
- exit 0
163
- fi
164
-
165
- echo ""
166
- echo "Updating session file..."
167
-
168
- # Build the Phase History additions
169
- PHASE_HISTORY_ADDITIONS=""
170
- HANDOFF_HISTORY_ADDITIONS=""
171
- PREV_END="$NOW"
172
-
173
- for transition in "${TRANSITIONS[@]}"; do
174
- IFS='|' read -r FROM_PHASE TO_PHASE FROM_AGENT TO_AGENT GATE <<< "$transition"
175
-
176
- # Add phase history row (close out the FROM phase)
177
- # We'll use NOW for ended time since we don't know actual times
178
- PHASE_HISTORY_ADDITIONS+="| $FROM_PHASE | - | $NOW | - |\n"
179
-
180
- # Add handoff history row
181
- HANDOFF_HISTORY_ADDITIONS+="| $FROM_AGENT | $TO_AGENT | $GATE | PASSED | $NOW |\n"
182
- done
183
-
184
- # Update the **Phase:** line
185
- sed -i.bak "s/^\*\*Phase:\*\*.*/\*\*Phase:\*\* $TARGET_PHASE/" "$SESSION_FILE"
186
-
187
- # Update the **Phase Started:** line
188
- sed -i.bak "s/^\*\*Phase Started:\*\*.*/\*\*Phase Started:\*\* $NOW/" "$SESSION_FILE"
189
-
190
- # Close out the current phase in Phase History (update the row that has "| - | - |" at the end)
191
- # This is tricky - we need to find the row for current phase and add end time
192
- # For now, we'll add a note about manual review needed
193
-
194
- # Add handoff history rows before the "## Story Context" section
195
- if [[ -n "$HANDOFF_HISTORY_ADDITIONS" ]]; then
196
- # Find the last handoff history row and add after it
197
- # The handoff history table ends before a blank line or next section
198
-
199
- # Use awk to insert after the last handoff history row
200
- awk -v additions="$HANDOFF_HISTORY_ADDITIONS" '
201
- /^\| .* \| .* \| .* \| .* \| .*\|$/ && /PASSED|FAILED/ {
202
- last_handoff = NR
203
- last_handoff_line = $0
204
- }
205
- {
206
- print
207
- if (NR == last_handoff && additions != "") {
208
- printf "%s", additions
209
- }
210
- }
211
- ' "$SESSION_FILE" > "$SESSION_FILE.tmp" && mv "$SESSION_FILE.tmp" "$SESSION_FILE"
212
- fi
213
-
214
- # Clean up backup
215
- rm -f "$SESSION_FILE.bak"
216
-
217
- echo ""
218
- echo "✓ Session file updated"
219
- echo " Phase: $CURRENT_PHASE → $TARGET_PHASE"
220
- echo " Handoffs added: ${#TRANSITIONS[@]}"
221
- echo ""
222
- echo "Note: Phase History end times set to now. Review and adjust if needed."
2
+ # DEPRECATED: Use `pf workflow fix-phase` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: fix-session-phase.sh is deprecated. Use: pf workflow fix-phase $*" >&2
5
+ exec pf workflow fix-phase "$@"
@@ -1,13 +1,5 @@
1
- #!/usr/bin/env bash
2
- # get-workflow-type.sh - Determine if a workflow is phased or stepped
3
- #
4
- # Usage: .pennyfarthing/scripts/workflow/get-workflow-type.sh <workflow-name>
5
- #
6
- # Returns: "phased" or "stepped"
7
- # Exit 1 if workflow not found
8
-
9
- set -euo pipefail
10
-
11
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
-
13
- exec python3 "$SCRIPT_DIR/get-workflow-type.py" "$@"
1
+ #!/bin/bash
2
+ # DEPRECATED: Use `pf workflow type` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: get-workflow-type.sh is deprecated. Use: pf workflow type $*" >&2
5
+ exec pf workflow type "$@"
@@ -1,124 +1,5 @@
1
1
  #!/bin/bash
2
- # List all available workflows with type indicators
3
- # Usage: .pennyfarthing/scripts/workflow/list-workflows.sh
4
- # or: Invoked with PROJECT_ROOT already set
5
- #
6
- # MSSCI-12083: Added type, steps, and modes columns
7
-
8
- set -euo pipefail
9
-
10
- # Find project root
11
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
12
-
13
- WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
14
-
15
- if [[ ! -d "$WORKFLOWS_DIR" ]]; then
16
- echo "Error: Workflows directory not found at $WORKFLOWS_DIR"
17
- exit 1
18
- fi
19
-
20
- if ! command -v yq &> /dev/null; then
21
- echo "Error: yq is required but not installed"
22
- echo "Install with: brew install yq"
23
- exit 1
24
- fi
25
-
26
- echo "# Available Workflows"
27
- echo ""
28
- echo "| Workflow | Type | Default | Steps/Phases | Modes | Description |"
29
- echo "|----------|------|---------|--------------|-------|-------------|"
30
-
31
- # Find all workflow YAML files: top-level *.yaml and subdirectory workflow.yaml files
32
- workflow_files=()
33
- while IFS= read -r -d '' f; do
34
- workflow_files+=("$f")
35
- done < <(find -L "$WORKFLOWS_DIR" -maxdepth 1 -name "*.yaml" -print0 2>/dev/null)
36
- while IFS= read -r -d '' f; do
37
- workflow_files+=("$f")
38
- done < <(find -L "$WORKFLOWS_DIR" -mindepth 2 -name "workflow.yaml" -print0 2>/dev/null)
39
-
40
- # Exit early if no workflows found
41
- if [[ ${#workflow_files[@]} -eq 0 ]]; then
42
- echo "No workflows found in $WORKFLOWS_DIR"
43
- exit 0
44
- fi
45
-
46
- # Sort by workflow name for consistent output
47
- IFS=$'\n' sorted_files=($(printf '%s\n' "${workflow_files[@]}" | sort))
48
- unset IFS
49
-
50
- for f in "${sorted_files[@]}"; do
51
- [[ -f "$f" ]] || continue
52
-
53
- name=$(yq eval '.workflow.name' "$f")
54
- desc=$(yq eval '.workflow.description' "$f" | head -1)
55
- is_default=$(yq eval '.workflow.triggers.default // false' "$f")
56
-
57
- # Detect workflow type (stepped, phased, or procedural)
58
- # Stepped workflows have .workflow.type == "stepped" or .workflow.steps
59
- # Procedural workflows have .workflow.type == "procedural" (BMAD reference workflows)
60
- workflow_type=$(yq eval '.workflow.type // "phased"' "$f")
61
- has_steps=$(yq eval '.workflow.steps != null' "$f")
62
-
63
- if [[ "$has_steps" == "true" ]] || [[ "$workflow_type" == "stepped" ]]; then
64
- type_col="stepped"
65
- # Count step files if steps.path is defined
66
- steps_path=$(yq eval '.workflow.steps.path // ""' "$f")
67
- steps_pattern=$(yq eval '.workflow.steps.pattern // "step-*.md"' "$f")
68
- # Resolve steps_path relative to the workflow file's directory
69
- workflow_dir=$(dirname "$f")
70
- if [[ -n "$steps_path" ]]; then
71
- # Handle relative paths (./steps/ or steps/)
72
- if [[ "$steps_path" == ./* ]]; then
73
- resolved_path="$workflow_dir/${steps_path#./}"
74
- elif [[ "$steps_path" != /* ]]; then
75
- resolved_path="$workflow_dir/$steps_path"
76
- else
77
- resolved_path="$steps_path"
78
- fi
79
- if [[ -d "$resolved_path" ]]; then
80
- step_count=$(find "$resolved_path" -maxdepth 1 -name "step-*.md" 2>/dev/null | wc -l | tr -d ' ')
81
- steps_col="${step_count} steps"
82
- else
83
- steps_col="-"
84
- fi
85
- else
86
- steps_col="-"
87
- fi
88
- elif [[ "$workflow_type" == "procedural" ]]; then
89
- type_col="procedural"
90
- # Procedural workflows use instructions.md instead of phases/steps
91
- steps_col="instructions"
92
- else
93
- type_col="phased"
94
- # Count phases for phased workflows
95
- phase_count=$(yq eval '.workflow.phases | length' "$f")
96
- steps_col="${phase_count} phases"
97
- fi
98
-
99
- # Default column
100
- if [[ "$is_default" == "true" ]]; then
101
- default_col="yes"
102
- else
103
- default_col="no"
104
- fi
105
-
106
- # Modes column (for tri-modal workflows)
107
- modes=$(yq eval '.workflow.modes.available // []' "$f")
108
- if [[ "$modes" != "[]" ]] && [[ "$modes" != "null" ]]; then
109
- # Format as comma-separated list
110
- modes_col=$(yq eval '.workflow.modes.available | join(",")' "$f")
111
- else
112
- modes_col="-"
113
- fi
114
-
115
- echo "| $name | $type_col | $default_col | $steps_col | $modes_col | $desc |"
116
- done
117
-
118
- echo ""
119
- echo "**Legend:**"
120
- echo "- **phased**: Agent-driven workflow (SM → TEA → Dev → Reviewer)"
121
- echo "- **stepped**: Step-by-step guided workflow with progressive disclosure"
122
- echo "- **procedural**: BMAD reference workflow with instructions file"
123
- echo ""
124
- echo "Use \`/workflow show <name>\` for workflow details."
2
+ # DEPRECATED: Use `pf workflow list` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: list-workflows.sh is deprecated. Use: pf workflow list" >&2
5
+ exec pf workflow list "$@"
@@ -1,34 +1,5 @@
1
1
  #!/bin/bash
2
- # Get the agent that owns a phase in a workflow
3
- # Usage: phase-owner.sh <workflow> <phase>
4
- # Returns: agent name (e.g., "dev", "tea", "reviewer", "sm")
5
-
6
- set -euo pipefail
7
-
8
- WORKFLOW="${1:-}"
9
- PHASE="${2:-}"
10
-
11
- if [[ -z "$WORKFLOW" || -z "$PHASE" ]]; then
12
- echo "Usage: phase-owner.sh <workflow> <phase>" >&2
13
- exit 1
14
- fi
15
-
16
- # Find project root
17
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
18
-
19
- WORKFLOW_FILE="$PROJECT_ROOT/.pennyfarthing/workflows/${WORKFLOW}.yaml"
20
-
21
- if [[ ! -f "$WORKFLOW_FILE" ]]; then
22
- echo "Error: Workflow '$WORKFLOW' not found" >&2
23
- exit 1
24
- fi
25
-
26
- # Query the agent for this phase
27
- AGENT=$(yq eval ".workflow.phases[] | select(.name == \"$PHASE\") | .agent" "$WORKFLOW_FILE" 2>/dev/null)
28
-
29
- if [[ -z "$AGENT" || "$AGENT" == "null" ]]; then
30
- echo "Error: Phase '$PHASE' not found in workflow '$WORKFLOW'" >&2
31
- exit 1
32
- fi
33
-
34
- echo "$AGENT"
2
+ # DEPRECATED: Use `pf workflow phase-check` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: phase-owner.sh is deprecated. Use: pf workflow phase-check $*" >&2
5
+ exec pf workflow phase-check "$@"