@pennyfarthing/core 11.1.1 → 11.2.1

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 (487) hide show
  1. package/README.md +8 -8
  2. package/package.json +2 -1
  3. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  4. package/packages/core/dist/cli/commands/doctor.js +381 -66
  5. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  6. package/packages/core/dist/cli/commands/init.js +4 -4
  7. package/packages/core/dist/cli/commands/init.js.map +1 -1
  8. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  9. package/packages/core/dist/cli/commands/update.js +4 -5
  10. package/packages/core/dist/cli/commands/update.js.map +1 -1
  11. package/packages/core/dist/cli/utils/constants.d.ts +3 -8
  12. package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
  13. package/packages/core/dist/cli/utils/constants.js +3 -4
  14. package/packages/core/dist/cli/utils/constants.js.map +1 -1
  15. package/packages/core/dist/cli/utils/settings.d.ts +11 -0
  16. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
  17. package/packages/core/dist/cli/utils/settings.js +65 -29
  18. package/packages/core/dist/cli/utils/settings.js.map +1 -1
  19. package/packages/core/dist/cli/utils/symlinks.js +16 -16
  20. package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
  21. package/packages/core/dist/consultation/tandem-metrics.d.ts +91 -0
  22. package/packages/core/dist/consultation/tandem-metrics.d.ts.map +1 -0
  23. package/packages/core/dist/consultation/tandem-metrics.js +131 -0
  24. package/packages/core/dist/consultation/tandem-metrics.js.map +1 -0
  25. package/packages/core/dist/consultation/tandem-metrics.test.d.ts +18 -0
  26. package/packages/core/dist/consultation/tandem-metrics.test.d.ts.map +1 -0
  27. package/packages/core/dist/consultation/tandem-metrics.test.js +457 -0
  28. package/packages/core/dist/consultation/tandem-metrics.test.js.map +1 -0
  29. package/packages/core/dist/public/js/react/react.js +14 -14
  30. package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
  31. package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
  32. package/packages/core/dist/scripts/benchmark-integration.js +691 -0
  33. package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
  34. package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
  35. package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
  36. package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
  37. package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
  38. package/packages/core/dist/server/api/agent-load.js +1 -1
  39. package/packages/core/dist/server/api/agent-load.js.map +1 -1
  40. package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
  41. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  42. package/packages/core/dist/server/otlp-receiver.js +185 -24
  43. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  44. package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
  45. package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
  46. package/packages/core/dist/server/otlp-receiver.test.js +446 -0
  47. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
  48. package/packages/core/dist/server/server.d.ts +0 -3
  49. package/packages/core/dist/server/server.d.ts.map +1 -1
  50. package/packages/core/dist/server/server.js +3 -37
  51. package/packages/core/dist/server/server.js.map +1 -1
  52. package/packages/core/dist/server/server.test.d.ts +1 -1
  53. package/packages/core/dist/server/server.test.js +12 -23
  54. package/packages/core/dist/server/server.test.js.map +1 -1
  55. package/packages/core/dist/shared/capabilities.d.ts +88 -0
  56. package/packages/core/dist/shared/capabilities.d.ts.map +1 -0
  57. package/packages/core/dist/shared/capabilities.js +133 -0
  58. package/packages/core/dist/shared/capabilities.js.map +1 -0
  59. package/packages/core/dist/shared/capabilities.test.d.ts +2 -0
  60. package/packages/core/dist/shared/capabilities.test.d.ts.map +1 -0
  61. package/packages/core/dist/shared/capabilities.test.js +217 -0
  62. package/packages/core/dist/shared/capabilities.test.js.map +1 -0
  63. package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
  64. package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
  65. package/packages/core/dist/shared/portrait-resolver.js +27 -0
  66. package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
  67. package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
  68. package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
  69. package/packages/core/dist/shared/spawn-prompt.d.ts +47 -0
  70. package/packages/core/dist/shared/spawn-prompt.d.ts.map +1 -0
  71. package/packages/core/dist/shared/spawn-prompt.js +82 -0
  72. package/packages/core/dist/shared/spawn-prompt.js.map +1 -0
  73. package/packages/core/dist/shared/spawn-prompt.test.d.ts +2 -0
  74. package/packages/core/dist/shared/spawn-prompt.test.d.ts.map +1 -0
  75. package/packages/core/dist/shared/spawn-prompt.test.js +251 -0
  76. package/packages/core/dist/shared/spawn-prompt.test.js.map +1 -0
  77. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
  78. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
  79. package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
  80. package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
  81. package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts +18 -0
  82. package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts.map +1 -0
  83. package/packages/core/dist/workflow/tandem-workflow-templates.test.js +434 -0
  84. package/packages/core/dist/workflow/tandem-workflow-templates.test.js.map +1 -0
  85. package/packages/core/dist/workflow/workflow-schema.d.ts +32 -0
  86. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
  87. package/packages/core/dist/workflow/workflow-schema.js +120 -0
  88. package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
  89. package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -1
  90. package/packages/core/dist/workflow/workflow-schema.test.js +570 -1
  91. package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -1
  92. package/pennyfarthing-dist/agents/dev.md +7 -11
  93. package/pennyfarthing-dist/agents/reviewer.md +9 -3
  94. package/pennyfarthing-dist/agents/sm-finish.md +18 -1
  95. package/pennyfarthing-dist/agents/sm-setup.md +1 -1
  96. package/pennyfarthing-dist/agents/sm.md +2 -2
  97. package/pennyfarthing-dist/agents/tea.md +1 -1
  98. package/pennyfarthing-dist/agents/testing-runner.md +2 -1
  99. package/pennyfarthing-dist/commands/pf-chore.md +2 -2
  100. package/pennyfarthing-dist/commands/pf-git.md +4 -2
  101. package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
  102. package/pennyfarthing-dist/gates/approval.md +63 -0
  103. package/pennyfarthing-dist/gates/confidence-sm.md +71 -0
  104. package/pennyfarthing-dist/gates/context-ok.md +56 -0
  105. package/pennyfarthing-dist/gates/evaluations/confidence-sm.md +54 -0
  106. package/pennyfarthing-dist/gates/quality-pass.md +67 -0
  107. package/pennyfarthing-dist/gates/tests-fail.md +84 -0
  108. package/pennyfarthing-dist/gates/tests-pass.md +79 -0
  109. package/pennyfarthing-dist/guides/agent-behavior.md +23 -19
  110. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
  111. package/pennyfarthing-dist/guides/bell-mode.md +1 -1
  112. package/pennyfarthing-dist/guides/bikerack.md +3 -3
  113. package/pennyfarthing-dist/guides/hooks.md +29 -29
  114. package/pennyfarthing-dist/guides/reflector.md +1 -1
  115. package/pennyfarthing-dist/guides/tandem-protocol.md +3 -3
  116. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  117. package/pennyfarthing-dist/guides/xml-tags.md +2 -2
  118. package/pennyfarthing-dist/scripts/README.md +1 -1
  119. package/pennyfarthing-dist/scripts/core/check-context.sh +3 -1
  120. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +5 -87
  121. package/pennyfarthing-dist/scripts/git/README.md +24 -14
  122. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
  123. package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
  124. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
  125. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
  126. package/pennyfarthing-dist/scripts/hooks/README.md +6 -6
  127. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  128. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +4 -183
  129. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +4 -95
  130. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +4 -65
  131. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +3 -31
  132. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
  133. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +27 -33
  134. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +4 -71
  135. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +3 -19
  136. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +4 -30
  137. package/pennyfarthing-dist/scripts/hooks/session-start.sh +3 -32
  138. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +4 -65
  139. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +4 -78
  140. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +4 -93
  141. package/pennyfarthing-dist/scripts/misc/README.md +1 -1
  142. package/pennyfarthing-dist/scripts/misc/statusline.sh +4 -301
  143. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
  144. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
  145. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
  146. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
  147. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
  148. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
  149. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
  150. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
  151. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
  152. package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
  153. package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
  154. package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
  155. package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
  156. package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
  157. package/pennyfarthing-dist/templates/settings.local.json.template +19 -10
  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-dist/workflows/tdd.yaml +11 -2
  165. package/pennyfarthing_scripts/CLAUDE.md +45 -14
  166. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  167. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  171. package/pennyfarthing_scripts/__pycache__/context.cpython-314.pyc +0 -0
  172. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  173. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  174. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  181. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  182. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  183. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  184. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  185. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  186. package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
  187. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  188. package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
  189. package/pennyfarthing_scripts/bc/cli.py +3 -5
  190. package/pennyfarthing_scripts/bellmode_hook.py +12 -296
  191. package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
  192. package/pennyfarthing_scripts/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
  193. package/pennyfarthing_scripts/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
  194. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  195. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  196. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  197. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  198. package/pennyfarthing_scripts/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  200. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  201. package/pennyfarthing_scripts/bikerack/__pycache__/events.cpython-314.pyc +0 -0
  202. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  203. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  206. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
  209. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  210. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  211. package/pennyfarthing_scripts/bikerack/audit_log_panel.py +119 -0
  212. package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
  213. package/pennyfarthing_scripts/bikerack/base_panel.py +87 -2
  214. package/pennyfarthing_scripts/bikerack/changed_panel.py +125 -29
  215. package/pennyfarthing_scripts/bikerack/context_meter_footer.py +88 -0
  216. package/pennyfarthing_scripts/bikerack/debug_panel.py +32 -2
  217. package/pennyfarthing_scripts/bikerack/diffs_panel.py +104 -17
  218. package/pennyfarthing_scripts/bikerack/events.py +28 -0
  219. package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
  220. package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
  221. package/pennyfarthing_scripts/bikerack/portrait_resolver.py +139 -0
  222. package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
  223. package/pennyfarthing_scripts/bikerack/sprint_panel.py +395 -32
  224. package/pennyfarthing_scripts/bikerack/story_detail_data.py +244 -0
  225. package/pennyfarthing_scripts/bikerack/story_detail_screen.py +176 -0
  226. package/pennyfarthing_scripts/bikerack/tui.py +575 -37
  227. package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
  228. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  229. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  230. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  231. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  232. package/pennyfarthing_scripts/cli.py +42 -65
  233. package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  235. package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  237. package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  238. package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  239. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  240. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  241. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  242. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  243. package/pennyfarthing_scripts/common/pr_config.py +38 -0
  244. package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  245. package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  247. package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  248. package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  249. package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/consultation/__init__.py +1 -0
  251. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/consultation/__pycache__/dialogue_manager.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/consultation/cli.py +149 -0
  255. package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
  256. package/pennyfarthing_scripts/context.py +3 -3
  257. package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  258. package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  259. package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  260. package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  261. package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  262. package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  263. package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  264. package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  265. package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  266. package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  267. package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  268. package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  269. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  270. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  271. package/pennyfarthing_scripts/git/__init__.py +12 -1
  272. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  273. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  274. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/git/create_branches.py +3 -4
  276. package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
  277. package/pennyfarthing_scripts/git/repos.py +196 -0
  278. package/pennyfarthing_scripts/git/status_all.py +27 -11
  279. package/pennyfarthing_scripts/git/worktree.py +302 -0
  280. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  281. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  282. package/pennyfarthing_scripts/git_group/cli.py +143 -40
  283. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  284. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  285. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  286. package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
  287. package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
  288. package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  289. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  290. package/pennyfarthing_scripts/handoff/cli.py +33 -1
  291. package/pennyfarthing_scripts/handoff/complete_phase.py +40 -0
  292. package/pennyfarthing_scripts/handoff/marker.py +15 -15
  293. package/pennyfarthing_scripts/handoff/phase_check.py +96 -0
  294. package/pennyfarthing_scripts/handoff/resolve_gate.py +18 -15
  295. package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  296. package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  297. package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  298. package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  299. package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/hooks/__init__.py +437 -0
  302. package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  303. package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
  304. package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-314.pyc +0 -0
  305. package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
  306. package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
  307. package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
  308. package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
  309. package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
  310. package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
  311. package/pennyfarthing_scripts/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
  312. package/pennyfarthing_scripts/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
  313. package/pennyfarthing_scripts/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
  314. package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
  315. package/pennyfarthing_scripts/hooks/bell_mode.py +215 -0
  316. package/pennyfarthing_scripts/hooks/cli.py +96 -0
  317. package/pennyfarthing_scripts/hooks/context_breaker.py +104 -0
  318. package/pennyfarthing_scripts/hooks/context_warning.py +66 -0
  319. package/pennyfarthing_scripts/hooks/cyclist_pretooluse.py +129 -0
  320. package/pennyfarthing_scripts/hooks/pre_edit_check.py +78 -0
  321. package/pennyfarthing_scripts/hooks/reflector_check.py +271 -0
  322. package/pennyfarthing_scripts/hooks/schema_validation.py +203 -0
  323. package/pennyfarthing_scripts/hooks/session_start.py +296 -0
  324. package/pennyfarthing_scripts/hooks/session_stop.py +111 -0
  325. package/pennyfarthing_scripts/hooks/sprint_yaml_validation.py +97 -0
  326. package/pennyfarthing_scripts/hooks/statusline.py +420 -0
  327. package/pennyfarthing_scripts/hooks.py +27 -446
  328. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  329. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  330. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  331. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  332. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  333. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  334. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  335. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  336. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  337. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  338. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  339. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  340. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  341. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  342. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  343. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  344. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  345. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  346. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  347. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  348. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  349. package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
  350. package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -0
  351. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  352. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  353. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  354. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  355. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  356. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  357. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  358. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  359. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  360. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  361. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  362. package/pennyfarthing_scripts/pretooluse_hook.py +3 -185
  363. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  364. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  365. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  366. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  367. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  368. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  369. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  370. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  371. package/pennyfarthing_scripts/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
  372. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  373. package/pennyfarthing_scripts/prime/heatmap.py +655 -0
  374. package/pennyfarthing_scripts/prime/workflow.py +2 -1
  375. package/pennyfarthing_scripts/schema_validation_hook.py +3 -298
  376. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  377. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  378. package/pennyfarthing_scripts/session_start_hook.py +4 -186
  379. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  380. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  381. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  382. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  383. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  384. package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  385. package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
  386. package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  387. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  388. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  389. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  390. package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  391. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  392. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  393. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  394. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  395. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  396. package/pennyfarthing_scripts/sprint/loader.py +15 -1
  397. package/pennyfarthing_scripts/sprint/story_update.py +19 -0
  398. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  399. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  400. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  401. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  402. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  403. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  404. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  405. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  406. package/pennyfarthing_scripts/tests/__pycache__/test_108_1_gate_migration.cpython-314-pytest-9.0.2.pyc +0 -0
  407. package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
  408. package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
  409. package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
  410. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  411. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  412. package/pennyfarthing_scripts/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
  413. package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  414. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  415. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
  416. package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
  417. package/pennyfarthing_scripts/tests/__pycache__/test_dialogue_manager.cpython-314-pytest-9.0.2.pyc +0 -0
  418. package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
  419. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  420. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  421. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  422. package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  423. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  424. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  425. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  426. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  427. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  428. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
  429. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  430. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  431. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  432. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  433. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  434. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  435. package/pennyfarthing_scripts/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
  436. package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
  437. package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
  438. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  439. package/pennyfarthing_scripts/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
  440. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  441. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  442. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  443. package/pennyfarthing_scripts/tests/test_bikerack.py +51 -51
  444. package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
  445. package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
  446. package/pennyfarthing_scripts/tests/test_sprint_panel.py +344 -265
  447. package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
  448. package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  449. package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
  450. package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  451. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  452. package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  453. package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  454. package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  455. package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  456. package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  457. package/pennyfarthing_scripts/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc +0 -0
  458. package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  459. package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
  460. package/pennyfarthing_scripts/validate/adapters/workflow.py +19 -0
  461. package/pennyfarthing_scripts/validate/cli.py +17 -5
  462. package/pennyfarthing_scripts/welcome_hook.py +3 -149
  463. package/pennyfarthing_scripts/workflow/__init__.py +40 -0
  464. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  465. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  466. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  467. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  468. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  469. package/pennyfarthing_scripts/workflow/cli.py +1100 -0
  470. package/pennyfarthing_scripts/workflow/helpers.py +241 -0
  471. package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
  472. package/pennyfarthing_scripts/workflow/state.py +112 -0
  473. package/pennyfarthing_scripts/workflow/team_lifecycle.py +257 -0
  474. package/packages/core/dist/scripts/theme-detail.test.d.ts +0 -10
  475. package/packages/core/dist/scripts/theme-detail.test.js +0 -199
  476. package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
  477. package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
  478. package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
  479. package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
  480. package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
  481. package/pennyfarthing_scripts/gate/__pycache__/__init__.cpython-314.pyc +0 -0
  482. package/pennyfarthing_scripts/gate/__pycache__/cli.cpython-314.pyc +0 -0
  483. package/pennyfarthing_scripts/gate/__pycache__/validate.cpython-314.pyc +0 -0
  484. package/pennyfarthing_scripts/tests/__pycache__/test_108_2_remove_handoff_fallback.cpython-314-pytest-9.0.2.pyc +0 -0
  485. package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
  486. package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
  487. package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -5,15 +5,16 @@ Usage:
5
5
  pf git [COMMAND] [ARGS]...
6
6
 
7
7
  Commands:
8
- status Check git status of all project repos
9
- cleanup Organize changes into proper commits/branches
10
- branches Create feature branches from a story
11
- release Interactive release with verification gates
8
+ status Check git status of all project repos
9
+ cleanup Organize changes into proper commits/branches
10
+ branches Create feature branches from a story
11
+ worktree Manage git worktrees for parallel work
12
+ install-hooks Install git hooks with .d/ dispatcher pattern
12
13
  """
13
14
 
14
- import click
15
+ import asyncio
15
16
 
16
- from pennyfarthing_scripts.common.config import get_project_root
17
+ import click
17
18
 
18
19
 
19
20
  @click.group()
@@ -22,10 +23,11 @@ def git():
22
23
 
23
24
  \b
24
25
  Commands:
25
- status - Check git status of all repos
26
- cleanup - Organize changes into commits/branches
27
- branches - Create feature branches from a story
28
- release - Interactive release with verification gates
26
+ status - Check git status of all repos
27
+ cleanup - Organize changes into commits/branches
28
+ branches - Create feature branches from a story
29
+ worktree - Manage git worktrees for parallel work
30
+ install-hooks - Install git hooks with .d/ dispatcher
29
31
  """
30
32
  pass
31
33
 
@@ -37,21 +39,38 @@ def status(brief: bool):
37
39
 
38
40
  Shows branch, uncommitted changes, and ahead/behind status for each repo.
39
41
  """
40
- import subprocess
42
+ from pennyfarthing_scripts.git.repos import get_repo_paths, load_repos_config
43
+ from pennyfarthing_scripts.git.status_all import (
44
+ format_status_brief,
45
+ format_status_full,
46
+ format_summary,
47
+ get_all_repo_status,
48
+ )
41
49
 
42
- root = get_project_root()
43
- script = root / ".pennyfarthing" / "scripts" / "git" / "git-status-all.sh"
50
+ repo_paths = get_repo_paths()
51
+ config = load_repos_config()
44
52
 
45
- if not script.is_file():
46
- click.echo("Error: git-status-all.sh not found", err=True)
47
- raise SystemExit(1)
53
+ # Build repo list with per-repo upstream refs
54
+ repos_with_upstream: list[tuple[str, object, str]] = []
55
+ for name, path in repo_paths:
56
+ upstream = config[name].upstream_ref if name in config else "origin/main"
57
+ repos_with_upstream.append((name, path, upstream))
58
+
59
+ statuses = asyncio.run(get_all_repo_status(repos_with_upstream))
48
60
 
49
- cmd = [str(script)]
50
61
  if brief:
51
- cmd.append("--brief")
62
+ click.echo(format_status_brief(statuses))
63
+ else:
64
+ click.echo("━" * 40)
65
+ click.echo(" Git Status - All Repos")
66
+ click.echo("━" * 40)
67
+ click.echo()
68
+ click.echo(format_status_full(statuses))
69
+ click.echo("━" * 40)
70
+ click.echo(format_summary(statuses))
52
71
 
53
- result = subprocess.run(cmd, cwd=str(root))
54
- raise SystemExit(result.returncode)
72
+ has_issues = any(not s.is_clean or s.has_unpushed for s in statuses)
73
+ raise SystemExit(1 if has_issues else 0)
55
74
 
56
75
 
57
76
  @git.command()
@@ -67,34 +86,118 @@ def cleanup():
67
86
 
68
87
 
69
88
  @git.command()
70
- @click.argument("story_id")
71
- def branches(story_id: str):
72
- """Create feature branches in both repos from a story.
89
+ @click.argument("branch_name")
90
+ @click.option(
91
+ "--repos",
92
+ type=click.Choice(["all", "api", "ui"]),
93
+ default="all",
94
+ help="Which repos to target",
95
+ )
96
+ def branches(branch_name: str, repos: str):
97
+ """Create feature branches across all configured repos.
73
98
 
74
99
  \b
75
100
  Arguments:
76
- STORY_ID - The story ID to create branches for (e.g., 86-3)
101
+ BRANCH_NAME - The branch name to create (e.g., feat/86-3-file-upload)
77
102
  """
78
- import subprocess
103
+ from pennyfarthing_scripts.git.create_branches import (
104
+ create_feature_branches,
105
+ detect_worktree,
106
+ filter_repos,
107
+ format_results,
108
+ )
109
+ from pennyfarthing_scripts.git.repos import get_repo_paths
110
+
111
+ is_worktree, worktree_name, _ = detect_worktree()
112
+ if is_worktree:
113
+ click.echo(f"📂 Detected worktree: {worktree_name}")
114
+ else:
115
+ click.echo("📂 Using main checkout")
116
+
117
+ all_repos = get_repo_paths()
118
+ filtered = filter_repos(all_repos, repos)
119
+
120
+ if not filtered:
121
+ click.echo(f"No repos match filter: {repos}", err=True)
122
+ raise SystemExit(1)
79
123
 
80
- root = get_project_root()
81
- script = root / ".pennyfarthing" / "scripts" / "git" / "create-branches.sh"
124
+ results = asyncio.run(create_feature_branches(filtered, branch_name))
125
+ click.echo(format_results(results, branch_name))
82
126
 
83
- if not script.is_file():
84
- click.echo("Error: create-branches.sh not found", err=True)
85
- raise SystemExit(1)
127
+ from pennyfarthing_scripts.git.create_branches import BranchAction
86
128
 
87
- result = subprocess.run([str(script), story_id], cwd=str(root))
88
- raise SystemExit(result.returncode)
129
+ has_errors = any(r.action == BranchAction.ERROR for r in results)
130
+ raise SystemExit(1 if has_errors else 0)
89
131
 
90
132
 
91
- @git.command()
92
- def release():
93
- """Interactive release with verification gates.
133
+ # Worktree subgroup
134
+ @git.group()
135
+ def worktree():
136
+ """Manage git worktrees for parallel development.
137
+
138
+ \b
139
+ Commands:
140
+ create - Create worktree(s) for parallel work
141
+ remove - Remove worktree and clean up
142
+ list - List all active worktrees
143
+ status - Show detailed worktree status
144
+ """
145
+ pass
94
146
 
95
- Starts the release stepped workflow via BikeLane.
96
- Equivalent to: /pf-workflow start release
147
+
148
+ @worktree.command("create")
149
+ @click.argument("name")
150
+ @click.argument("branch")
151
+ @click.option(
152
+ "--repos",
153
+ default="all",
154
+ help="Repos filter: all, api, ui, or comma-separated names",
155
+ )
156
+ def worktree_create(name: str, branch: str, repos: str):
157
+ """Create worktree(s) for parallel work.
158
+
159
+ \b
160
+ Arguments:
161
+ NAME - Worktree name (e.g., wt-5-3a)
162
+ BRANCH - Branch name (e.g., feat/5-3a-file-upload)
97
163
  """
98
- click.echo("Starting release workflow...")
99
- click.echo("Run: /pf-workflow start release")
100
- click.echo("Or: pf workflow start release")
164
+ from pennyfarthing_scripts.git.worktree import create_worktree
165
+
166
+ raise SystemExit(create_worktree(name, branch, repos))
167
+
168
+
169
+ @worktree.command("remove")
170
+ @click.argument("name")
171
+ def worktree_remove(name: str):
172
+ """Remove worktree and clean up."""
173
+ from pennyfarthing_scripts.git.worktree import remove_worktree
174
+
175
+ raise SystemExit(remove_worktree(name))
176
+
177
+
178
+ @worktree.command("list")
179
+ def worktree_list():
180
+ """List all active worktrees."""
181
+ from pennyfarthing_scripts.git.worktree import list_worktrees
182
+
183
+ raise SystemExit(list_worktrees())
184
+
185
+
186
+ @worktree.command("status")
187
+ def worktree_status():
188
+ """Show detailed worktree status."""
189
+ from pennyfarthing_scripts.git.worktree import show_worktree_status
190
+
191
+ raise SystemExit(show_worktree_status())
192
+
193
+
194
+ @git.command("install-hooks")
195
+ def install_hooks():
196
+ """Install git hooks with .d/ dispatcher pattern.
197
+
198
+ Creates .d/ directories, symlinks pennyfarthing hooks, and
199
+ migrates existing user hooks.
200
+ """
201
+ from pennyfarthing_scripts.git.hooks_installer import install_git_hooks
202
+
203
+ raise SystemExit(install_git_hooks())
@@ -4,8 +4,9 @@ Usage:
4
4
  pf handoff resolve-gate STORY_ID WORKFLOW PHASE
5
5
  pf handoff complete-phase STORY_ID WORKFLOW FROM_PHASE TO_PHASE GATE_TYPE
6
6
  pf handoff marker NEXT_AGENT [--error MESSAGE]
7
+ pf handoff phase-check AGENT
7
8
 
8
- Stories: 105-1, 105-4 (Script-First Handoff)
9
+ Stories: 105-1, 105-4 (Script-First Handoff), 110-8 (CLI Relay Handoff Fix)
9
10
  """
10
11
 
11
12
  from __future__ import annotations
@@ -22,6 +23,7 @@ def handoff():
22
23
  resolve-gate - Resolve gate for current phase
23
24
  complete-phase - Complete phase transition atomically
24
25
  marker - Generate AGENT_COMMAND handoff marker
26
+ phase-check - Check if agent owns current phase
25
27
  """
26
28
  pass
27
29
 
@@ -118,3 +120,33 @@ def marker_cmd(next_agent: str | None, error_msg: str | None):
118
120
  )
119
121
 
120
122
  click.echo(generate_marker(next_agent, error=error_msg))
123
+
124
+
125
+ @handoff.command("phase-check")
126
+ @click.argument("agent")
127
+ def phase_check_cmd(agent: str):
128
+ """Check if the requested agent owns the current workflow phase.
129
+
130
+ Returns a YAML block with action ("start" or "redirect"), the correct
131
+ agent, story ID, phase, and a human-readable message.
132
+
133
+ If the agent does not own the phase, generates a handoff marker for
134
+ the correct agent.
135
+
136
+ \b
137
+ Arguments:
138
+ AGENT - Agent to check (e.g., dev, tea, reviewer, sm)
139
+ """
140
+ from pennyfarthing_scripts.handoff.phase_check import phase_check_start
141
+
142
+ result = phase_check_start(agent)
143
+
144
+ import yaml
145
+
146
+ click.echo(yaml.dump({"PHASE_CHECK": result}, default_flow_style=False).rstrip())
147
+
148
+ if result["action"] == "redirect":
149
+ click.echo("")
150
+ from pennyfarthing_scripts.handoff.marker import generate_marker
151
+
152
+ click.echo(generate_marker(result["agent"]))
@@ -53,11 +53,36 @@ def complete_phase(
53
53
  }
54
54
 
55
55
  content = session_path.read_text()
56
+
57
+ # Guard: require assessment section before allowing gated phase transitions.
58
+ # Skip/manual transitions (e.g. setup→implement) don't need assessments.
59
+ if gate_type not in ("skip", "manual", "-", None, "") and not re.search(
60
+ r"^##\s+.*Assessment", content, re.MULTILINE
61
+ ):
62
+ return {
63
+ "status": "error",
64
+ "session_file": str(session_path),
65
+ "error": "No assessment found in session file. Write your assessment before completing the phase.",
66
+ }
67
+
56
68
  now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
57
69
 
58
70
  from_agent = _get_phase_agent(project_root, workflow, from_phase)
59
71
  to_agent = _get_phase_agent(project_root, workflow, to_phase)
60
72
 
73
+ # Update tandem line: remove existing, add if to_phase has tandem config
74
+ content = re.sub(r"\*\*Tandem:\*\*[^\n]*\n", "", content)
75
+ tandem = _get_phase_tandem(project_root, workflow, to_phase)
76
+ if tandem:
77
+ partner = tandem["partner"]
78
+ scope = tandem["scope"]
79
+ tandem_line = f"**Tandem:** {partner} ({scope})\n"
80
+ content = re.sub(
81
+ r"(\*\*Workflow:\*\*[^\n]*\n)",
82
+ rf"\1{tandem_line}",
83
+ content,
84
+ )
85
+
61
86
  # Update all **Phase:** lines to new phase
62
87
  content = re.sub(r"(\*\*Phase:\*\*) \S+", rf"\1 {to_phase}", content)
63
88
 
@@ -133,6 +158,21 @@ def _calc_duration(started_str: str, ended_str: str) -> str:
133
158
  return f"{hours}h {rem_minutes}m" if rem_minutes else f"{hours}h"
134
159
 
135
160
 
161
+ def _get_phase_tandem(project_root: Path, workflow: str, phase: str) -> dict | None:
162
+ """Return tandem config for a phase, or None if no tandem block."""
163
+ for name in [f"{workflow}.yaml", f"{workflow}/workflow.yaml"]:
164
+ path = project_root / ".pennyfarthing" / "workflows" / name
165
+ if path.exists():
166
+ try:
167
+ data = yaml.safe_load(path.read_text())
168
+ for p in data["workflow"]["phases"]:
169
+ if p["name"] == phase:
170
+ return p.get("tandem")
171
+ except Exception:
172
+ pass
173
+ return None
174
+
175
+
136
176
  def _get_phase_agent(project_root: Path, workflow: str, phase: str) -> str:
137
177
  for name in [f"{workflow}.yaml", f"{workflow}/workflow.yaml"]:
138
178
  path = project_root / ".pennyfarthing" / "workflows" / name
@@ -72,25 +72,25 @@ def generate_marker(
72
72
  fallback=f"Run `{cmd}` to continue",
73
73
  )
74
74
 
75
- # Non-Cyclist relay: invoke the next agent directly
76
- import subprocess
77
- try:
78
- result = subprocess.run(
79
- ["pf", "agent", "start", next_agent],
80
- capture_output=True,
81
- text=True,
82
- timeout=30,
75
+ # Non-Cyclist relay: return structured action for the agent to act on.
76
+ # The calling agent reads the `action` field and executes accordingly.
77
+ if ctx.use_tirepump:
78
+ return _block(
79
+ action="tirepump_handoff",
80
+ next_agent=next_agent,
81
+ fallback=f"Context is high ({pct}%). Run /clear then {cmd}",
82
+ context_percent=pct,
83
+ relay_mode=True,
83
84
  )
84
- agent_output = result.stdout.strip()
85
- except Exception as e:
86
- agent_output = f"Failed to invoke agent: {e}"
87
85
 
88
86
  return _block(
89
- fallback=f"Run `{cmd}` to continue{context_warning}",
90
- relay_mode=True,
87
+ action="inline_handoff",
88
+ next_agent=next_agent,
89
+ activation_command=f"pf agent start {next_agent} --tier handoff --quiet",
90
+ fallback=f"Run `{cmd}` to continue",
91
91
  context_percent=pct,
92
- invoke=cmd,
93
- ) + f"\n\n{agent_output}"
92
+ relay_mode=True,
93
+ )
94
94
 
95
95
 
96
96
  def _block(**fields: object) -> str:
@@ -0,0 +1,96 @@
1
+ """Phase check for agent activation.
2
+
3
+ Determines whether the requested agent owns the current workflow phase.
4
+ If not, returns a redirect to the correct agent. Replaces phase-check-start.sh.
5
+
6
+ Story: 110-8 (CLI Relay Handoff Fix)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pathlib import Path
12
+
13
+ from pennyfarthing_scripts.common.config import get_project_root
14
+ from pennyfarthing_scripts.prime.workflow import (
15
+ check_redirect,
16
+ detect_workflow_state,
17
+ find_active_session,
18
+ parse_session_header,
19
+ )
20
+
21
+
22
+ def phase_check_start(
23
+ agent_name: str,
24
+ project_root: Path | None = None,
25
+ ) -> dict:
26
+ """Check if requested agent owns current phase.
27
+
28
+ Args:
29
+ agent_name: Agent to check (e.g., "dev", "tea", "reviewer").
30
+ project_root: Project root path (auto-detected if not provided).
31
+
32
+ Returns:
33
+ Dict with:
34
+ action: "start" (proceed) or "redirect" (wrong agent)
35
+ agent: The agent that should run
36
+ story_id: Current story ID (if session exists)
37
+ phase: Current phase (if session exists)
38
+ phase_owner: Agent that owns the phase
39
+ message: Human-readable explanation
40
+ """
41
+ root = project_root or get_project_root()
42
+
43
+ # Find active session
44
+ session_file = find_active_session(root)
45
+ if not session_file:
46
+ return {
47
+ "action": "start",
48
+ "agent": agent_name,
49
+ "story_id": None,
50
+ "phase": None,
51
+ "phase_owner": None,
52
+ "message": f"No active session — starting {agent_name}",
53
+ }
54
+
55
+ # Parse session header
56
+ header = parse_session_header(session_file)
57
+ story_id = header.get("story_id")
58
+ workflow = header.get("workflow", "tdd")
59
+ phase = header.get("phase")
60
+
61
+ if not phase:
62
+ return {
63
+ "action": "start",
64
+ "agent": agent_name,
65
+ "story_id": story_id,
66
+ "phase": None,
67
+ "phase_owner": None,
68
+ "message": f"No phase detected — starting {agent_name}",
69
+ }
70
+
71
+ # Use detect_workflow_state + check_redirect for consistent logic
72
+ workflow_status = detect_workflow_state(root)
73
+ redirect = check_redirect(workflow_status, agent_name)
74
+
75
+ if redirect:
76
+ target_agent, reason = redirect
77
+ return {
78
+ "action": "redirect",
79
+ "agent": target_agent,
80
+ "story_id": story_id,
81
+ "phase": phase,
82
+ "phase_owner": target_agent,
83
+ "message": (
84
+ f"Story {story_id} is in '{phase}' phase "
85
+ f"(workflow: {workflow}) — owned by {target_agent}"
86
+ ),
87
+ }
88
+
89
+ return {
90
+ "action": "start",
91
+ "agent": agent_name,
92
+ "story_id": story_id,
93
+ "phase": phase,
94
+ "phase_owner": agent_name,
95
+ "message": f"Agent {agent_name} owns phase '{phase}' — proceeding",
96
+ }
@@ -1,14 +1,14 @@
1
1
  """Resolve gate for current workflow phase.
2
2
 
3
- Reads workflow YAML, finds current phase gate, checks for assessment
4
- section in session file, and returns a structured RESOLVE_RESULT.
3
+ Reads workflow YAML, finds current phase gate, and returns gate info.
4
+ Assessment checks are enforced in complete_phase (not here) to avoid
5
+ race conditions where agents call resolve-gate before writing assessments.
5
6
 
6
7
  Story: 105-1 (Script-First Handoff)
7
8
  """
8
9
 
9
10
  from __future__ import annotations
10
11
 
11
- import re
12
12
  from pathlib import Path
13
13
 
14
14
  import yaml
@@ -67,7 +67,19 @@ def resolve_gate(
67
67
 
68
68
  gate = current_phase.get("gate")
69
69
 
70
- if current_idx + 1 < len(phases):
70
+ # Support explicit next: directive for non-linear phase routing
71
+ explicit_next = current_phase.get("next")
72
+ if explicit_next:
73
+ nxt = next((p for p in phases if p["name"] == explicit_next), None)
74
+ if nxt:
75
+ next_phase = nxt["name"]
76
+ next_agent = nxt["agent"]
77
+ else:
78
+ return _result(
79
+ status="error",
80
+ error=f"Phase '{explicit_next}' referenced by next: not found in workflow '{workflow}'",
81
+ )
82
+ elif current_idx + 1 < len(phases):
71
83
  nxt = phases[current_idx + 1]
72
84
  next_phase = nxt["name"]
73
85
  next_agent = nxt["agent"]
@@ -95,22 +107,13 @@ def resolve_gate(
95
107
  assessment_found=True,
96
108
  )
97
109
 
98
- session_path = project_root / ".session" / f"{story_id}-session.md"
99
- assessment_found = False
100
- if session_path.exists():
101
- content = session_path.read_text()
102
- assessment_found = bool(
103
- re.search(r"^##\s+.*Assessment", content, re.MULTILINE)
104
- )
105
-
106
- status = "ready" if assessment_found else "blocked"
107
110
  return _result(
108
- status=status,
111
+ status="ready",
109
112
  gate_type=gate_type,
110
113
  gate_file=gate_file,
111
114
  next_agent=next_agent,
112
115
  next_phase=next_phase,
113
- assessment_found=assessment_found,
116
+ assessment_found=True,
114
117
  )
115
118
 
116
119