@pennyfarthing/core 11.4.0 → 11.5.0-alpha.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 (511) hide show
  1. package/package.json +1 -1
  2. package/packages/core/dist/cli/commands/cyclist.js +1 -1
  3. package/packages/core/dist/cli/commands/cyclist.js.map +1 -1
  4. package/packages/core/dist/cli/commands/cyclist.test.js +3 -3
  5. package/packages/core/dist/cli/commands/cyclist.test.js.map +1 -1
  6. package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.d.ts +22 -0
  7. package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.d.ts.map +1 -0
  8. package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.js +161 -0
  9. package/packages/core/dist/cli/commands/doctor-persona-config-false-negative.test.js.map +1 -0
  10. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  11. package/packages/core/dist/cli/commands/doctor.js +101 -33
  12. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  13. package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
  14. package/packages/core/dist/cli/commands/init.js +33 -13
  15. package/packages/core/dist/cli/commands/init.js.map +1 -1
  16. package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts +17 -0
  17. package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts.map +1 -0
  18. package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js +470 -0
  19. package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js.map +1 -0
  20. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  21. package/packages/core/dist/cli/commands/update.js +68 -17
  22. package/packages/core/dist/cli/commands/update.js.map +1 -1
  23. package/packages/core/dist/cli/cyclist-migration.test.d.ts +16 -0
  24. package/packages/core/dist/cli/cyclist-migration.test.d.ts.map +1 -0
  25. package/packages/core/dist/cli/cyclist-migration.test.js +229 -0
  26. package/packages/core/dist/cli/cyclist-migration.test.js.map +1 -0
  27. package/packages/core/dist/cli/index.js +2 -21
  28. package/packages/core/dist/cli/index.js.map +1 -1
  29. package/packages/core/dist/cli/utils/node-modules.d.ts +7 -0
  30. package/packages/core/dist/cli/utils/node-modules.d.ts.map +1 -1
  31. package/packages/core/dist/cli/utils/node-modules.js +39 -0
  32. package/packages/core/dist/cli/utils/node-modules.js.map +1 -1
  33. package/packages/core/dist/cli/utils/settings.d.ts +1 -1
  34. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
  35. package/packages/core/dist/cli/utils/settings.js +24 -21
  36. package/packages/core/dist/cli/utils/settings.js.map +1 -1
  37. package/packages/core/dist/cli/utils/stale-artifacts.d.ts +59 -0
  38. package/packages/core/dist/cli/utils/stale-artifacts.d.ts.map +1 -0
  39. package/packages/core/dist/cli/utils/stale-artifacts.js +163 -0
  40. package/packages/core/dist/cli/utils/stale-artifacts.js.map +1 -0
  41. package/packages/core/dist/public/css/react.css +1 -1
  42. package/packages/core/dist/public/js/react/react.js +39 -39
  43. package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
  44. package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
  45. package/packages/core/dist/scripts/benchmark-integration.js +691 -0
  46. package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
  47. package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
  48. package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
  49. package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
  50. package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
  51. package/packages/core/dist/scripts/theme-detail.test.d.ts.map +1 -0
  52. package/packages/core/dist/scripts/theme-detail.test.js.map +1 -0
  53. package/packages/core/dist/server/api/context.d.ts.map +1 -1
  54. package/packages/core/dist/server/api/context.js +23 -5
  55. package/packages/core/dist/server/api/context.js.map +1 -1
  56. package/packages/core/dist/server/api/index.d.ts +0 -1
  57. package/packages/core/dist/server/api/index.d.ts.map +1 -1
  58. package/packages/core/dist/server/api/index.js +0 -2
  59. package/packages/core/dist/server/api/index.js.map +1 -1
  60. package/packages/core/dist/server/api/settings.d.ts.map +1 -1
  61. package/packages/core/dist/server/api/settings.js +6 -0
  62. package/packages/core/dist/server/api/settings.js.map +1 -1
  63. package/packages/core/dist/server/otlp-receiver.d.ts +0 -4
  64. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  65. package/packages/core/dist/server/otlp-receiver.js +0 -18
  66. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  67. package/packages/core/dist/server/otlp-receiver.test.js +0 -27
  68. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -1
  69. package/packages/core/dist/server/server.d.ts +1 -1
  70. package/packages/core/dist/server/server.d.ts.map +1 -1
  71. package/packages/core/dist/server/server.js +2 -4
  72. package/packages/core/dist/server/server.js.map +1 -1
  73. package/packages/core/dist/workflow/cross-entity-validation.d.ts.map +1 -1
  74. package/packages/core/dist/workflow/cross-entity-validation.js.map +1 -1
  75. package/packages/core/src/public/App.tsx +0 -2
  76. package/packages/core/src/public/components/BikeRackWorkspace.tsx +0 -2
  77. package/packages/core/src/public/components/DockviewWorkspace.tsx +0 -4
  78. package/packages/core/src/public/components/StandalonePanel.tsx +0 -2
  79. package/packages/core/src/public/components/panels/SettingsPanel.tsx +83 -283
  80. package/packages/core/src/public/components/panels/SprintPanel.tsx +9 -1
  81. package/packages/core/src/public/components/panels/index.ts +0 -1
  82. package/packages/core/src/public/hooks/index.ts +0 -3
  83. package/packages/core/src/public/hooks/useSprint.ts +11 -2
  84. package/packages/core/src/public/images/cyclist-tandem-source.png +0 -0
  85. package/packages/core/src/public/styles/tailwind.css +0 -101
  86. package/pennyfarthing-dist/guides/bikerack.md +94 -0
  87. package/pennyfarthing-dist/personas/themes/firefly.yaml +12 -12
  88. package/pennyfarthing-dist/pf/__pycache__/__init__.cpython-311.pyc +0 -0
  89. package/pennyfarthing-dist/pf/__pycache__/__init__.cpython-314.pyc +0 -0
  90. package/pennyfarthing-dist/pf/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  91. package/pennyfarthing-dist/pf/__pycache__/cli.cpython-311.pyc +0 -0
  92. package/pennyfarthing-dist/pf/__pycache__/cli.cpython-314.pyc +0 -0
  93. package/pennyfarthing-dist/pf/__pycache__/config.cpython-314.pyc +0 -0
  94. package/pennyfarthing-dist/pf/__pycache__/context.cpython-311.pyc +0 -0
  95. package/pennyfarthing-dist/pf/__pycache__/context.cpython-314.pyc +0 -0
  96. package/pennyfarthing-dist/pf/__pycache__/hooks.cpython-314.pyc +0 -0
  97. package/pennyfarthing-dist/pf/__pycache__/jira.cpython-314.pyc +0 -0
  98. package/pennyfarthing-dist/pf/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  99. package/pennyfarthing-dist/pf/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  100. package/pennyfarthing-dist/pf/__pycache__/jira_sync.cpython-314.pyc +0 -0
  101. package/pennyfarthing-dist/pf/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  102. package/pennyfarthing-dist/pf/__pycache__/output.cpython-314.pyc +0 -0
  103. package/pennyfarthing-dist/pf/__pycache__/patch_mode.cpython-314.pyc +0 -0
  104. package/pennyfarthing-dist/pf/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  105. package/pennyfarthing-dist/pf/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  106. package/pennyfarthing-dist/pf/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  107. package/pennyfarthing-dist/pf/__pycache__/sprint.cpython-314.pyc +0 -0
  108. package/pennyfarthing-dist/pf/__pycache__/workflow.cpython-311.pyc +0 -0
  109. package/pennyfarthing-dist/pf/__pycache__/workflow.cpython-314.pyc +0 -0
  110. package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-311.pyc +0 -0
  111. package/pennyfarthing-dist/pf/bc/__pycache__/__init__.cpython-314.pyc +0 -0
  112. package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-311.pyc +0 -0
  113. package/pennyfarthing-dist/pf/bc/__pycache__/cli.cpython-314.pyc +0 -0
  114. package/pennyfarthing-dist/pf/bc/__pycache__/focus.cpython-311.pyc +0 -0
  115. package/pennyfarthing-dist/pf/bc/__pycache__/focus.cpython-314.pyc +0 -0
  116. package/pennyfarthing-dist/pf/bc/__pycache__/split.cpython-314.pyc +0 -0
  117. package/pennyfarthing-dist/pf/bc/cli.py +0 -1
  118. package/pennyfarthing-dist/pf/bc/focus.py +0 -1
  119. package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-311.pyc +0 -0
  120. package/pennyfarthing-dist/pf/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
  121. package/pennyfarthing-dist/pf/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
  122. package/pennyfarthing-dist/pf/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
  123. package/pennyfarthing-dist/pf/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  124. package/pennyfarthing-dist/pf/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  125. package/pennyfarthing-dist/pf/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  126. package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.cpython-311.pyc +0 -0
  127. package/pennyfarthing-dist/pf/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  128. package/pennyfarthing-dist/pf/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
  129. package/pennyfarthing-dist/pf/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  130. package/pennyfarthing-dist/pf/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  131. package/pennyfarthing-dist/pf/bikerack/__pycache__/events.cpython-314.pyc +0 -0
  132. package/pennyfarthing-dist/pf/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  133. package/pennyfarthing-dist/pf/bikerack/__pycache__/launcher.cpython-311.pyc +0 -0
  134. package/pennyfarthing-dist/pf/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  135. package/pennyfarthing-dist/pf/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
  136. package/pennyfarthing-dist/pf/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  137. package/pennyfarthing-dist/pf/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  138. package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
  139. package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
  140. package/pennyfarthing-dist/pf/bikerack/__pycache__/story_detail_widget.cpython-314.pyc +0 -0
  141. package/pennyfarthing-dist/pf/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  142. package/pennyfarthing-dist/pf/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  143. package/pennyfarthing-dist/pf/bikerack/context_meter_footer.py +115 -35
  144. package/pennyfarthing-dist/pf/bikerack/portrait_resolver.py +14 -2
  145. package/pennyfarthing-dist/pf/bikerack/progress_panel.py +54 -0
  146. package/pennyfarthing-dist/pf/bikerack/sprint_panel.py +58 -0
  147. package/pennyfarthing-dist/pf/bikerack/story_detail_screen.py +10 -105
  148. package/pennyfarthing-dist/pf/bikerack/story_detail_widget.py +167 -0
  149. package/pennyfarthing-dist/pf/bikerack/tui.py +140 -50
  150. package/pennyfarthing-dist/pf/bmad/__pycache__/__init__.cpython-314.pyc +0 -0
  151. package/pennyfarthing-dist/pf/bmad/__pycache__/cli.cpython-314.pyc +0 -0
  152. package/pennyfarthing-dist/pf/bmad/cli.py +0 -1
  153. package/pennyfarthing-dist/pf/bmad/importer.py +0 -1
  154. package/pennyfarthing-dist/pf/bmad/parser.py +0 -1
  155. package/pennyfarthing-dist/pf/bmad/sync.py +1 -3
  156. package/pennyfarthing-dist/pf/bmad/test_parser.py +0 -4
  157. package/pennyfarthing-dist/pf/bmad/test_sync.py +0 -3
  158. package/pennyfarthing-dist/pf/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  159. package/pennyfarthing-dist/pf/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  160. package/pennyfarthing-dist/pf/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  161. package/pennyfarthing-dist/pf/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  162. package/pennyfarthing-dist/pf/brownfield/cli.py +1 -1
  163. package/pennyfarthing-dist/pf/cli.py +145 -111
  164. package/pennyfarthing-dist/pf/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  165. package/pennyfarthing-dist/pf/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  166. package/pennyfarthing-dist/pf/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  167. package/pennyfarthing-dist/pf/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  168. package/pennyfarthing-dist/pf/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  169. package/pennyfarthing-dist/pf/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  170. package/pennyfarthing-dist/pf/common/__init__.py +2 -0
  171. package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-311.pyc +0 -0
  172. package/pennyfarthing-dist/pf/common/__pycache__/__init__.cpython-314.pyc +0 -0
  173. package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-311.pyc +0 -0
  174. package/pennyfarthing-dist/pf/common/__pycache__/config.cpython-314.pyc +0 -0
  175. package/pennyfarthing-dist/pf/common/__pycache__/output.cpython-311.pyc +0 -0
  176. package/pennyfarthing-dist/pf/common/__pycache__/output.cpython-314.pyc +0 -0
  177. package/pennyfarthing-dist/pf/common/__pycache__/pr_config.cpython-314.pyc +0 -0
  178. package/pennyfarthing-dist/pf/common/__pycache__/themes.cpython-314.pyc +0 -0
  179. package/pennyfarthing-dist/pf/common/config.py +43 -0
  180. package/pennyfarthing-dist/pf/common/themes.py +7 -5
  181. package/pennyfarthing-dist/pf/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  182. package/pennyfarthing-dist/pf/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  183. package/pennyfarthing-dist/pf/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  184. package/pennyfarthing-dist/pf/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  185. package/pennyfarthing-dist/pf/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  186. package/pennyfarthing-dist/pf/complexity/__pycache__/models.cpython-314.pyc +0 -0
  187. package/pennyfarthing-dist/pf/consultation/__pycache__/__init__.cpython-311.pyc +0 -0
  188. package/pennyfarthing-dist/pf/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  189. package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-311.pyc +0 -0
  190. package/pennyfarthing-dist/pf/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  191. package/pennyfarthing-dist/pf/consultation/__pycache__/dialogue_manager.cpython-314.pyc +0 -0
  192. package/pennyfarthing-dist/pf/context.py +1 -1
  193. package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.cpython-311.pyc +0 -0
  194. package/pennyfarthing-dist/pf/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  195. package/pennyfarthing-dist/pf/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  196. package/pennyfarthing-dist/pf/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  197. package/pennyfarthing-dist/pf/deadcode/__pycache__/cli.cpython-311.pyc +0 -0
  198. package/pennyfarthing-dist/pf/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  199. package/pennyfarthing-dist/pf/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  200. package/pennyfarthing-dist/pf/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  201. package/pennyfarthing-dist/pf/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  202. package/pennyfarthing-dist/pf/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  203. package/pennyfarthing-dist/pf/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  204. package/pennyfarthing-dist/pf/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  205. package/pennyfarthing-dist/pf/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  206. package/pennyfarthing-dist/pf/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  207. package/pennyfarthing-dist/pf/epic/__pycache__/__init__.cpython-311.pyc +0 -0
  208. package/pennyfarthing-dist/pf/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  209. package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-311.pyc +0 -0
  210. package/pennyfarthing-dist/pf/epic/__pycache__/cli.cpython-314.pyc +0 -0
  211. package/pennyfarthing-dist/pf/git/__pycache__/__init__.cpython-314.pyc +0 -0
  212. package/pennyfarthing-dist/pf/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  213. package/pennyfarthing-dist/pf/git/__pycache__/status_all.cpython-314.pyc +0 -0
  214. package/pennyfarthing-dist/pf/git/hooks_installer.py +7 -6
  215. package/pennyfarthing-dist/pf/git_group/__pycache__/__init__.cpython-311.pyc +0 -0
  216. package/pennyfarthing-dist/pf/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  217. package/pennyfarthing-dist/pf/git_group/__pycache__/cli.cpython-311.pyc +0 -0
  218. package/pennyfarthing-dist/pf/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  219. package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-311.pyc +0 -0
  220. package/pennyfarthing-dist/pf/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  221. package/pennyfarthing-dist/pf/handoff/__pycache__/cli.cpython-311.pyc +0 -0
  222. package/pennyfarthing-dist/pf/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  223. package/pennyfarthing-dist/pf/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  224. package/pennyfarthing-dist/pf/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
  225. package/pennyfarthing-dist/pf/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
  226. package/pennyfarthing-dist/pf/handoff/__pycache__/marker.cpython-314.pyc +0 -0
  227. package/pennyfarthing-dist/pf/handoff/__pycache__/phase_check.cpython-314.pyc +0 -0
  228. package/pennyfarthing-dist/pf/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  229. package/pennyfarthing-dist/pf/handoff/gate_file.py +5 -1
  230. package/pennyfarthing-dist/pf/healthscore/__pycache__/__init__.cpython-311.pyc +0 -0
  231. package/pennyfarthing-dist/pf/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  232. package/pennyfarthing-dist/pf/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  233. package/pennyfarthing-dist/pf/healthscore/__pycache__/analyze.cpython-311.pyc +0 -0
  234. package/pennyfarthing-dist/pf/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  235. package/pennyfarthing-dist/pf/healthscore/__pycache__/cli.cpython-311.pyc +0 -0
  236. package/pennyfarthing-dist/pf/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  237. package/pennyfarthing-dist/pf/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  238. package/pennyfarthing-dist/pf/healthscore/__pycache__/models.cpython-311.pyc +0 -0
  239. package/pennyfarthing-dist/pf/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  240. package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  241. package/pennyfarthing-dist/pf/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  242. package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-311.pyc +0 -0
  243. package/pennyfarthing-dist/pf/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
  244. package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-311.pyc +0 -0
  245. package/pennyfarthing-dist/pf/hooks/__pycache__/cli.cpython-314.pyc +0 -0
  246. package/pennyfarthing-dist/pf/hooks/__pycache__/context_breaker.cpython-311.pyc +0 -0
  247. package/pennyfarthing-dist/pf/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
  248. package/pennyfarthing-dist/pf/hooks/__pycache__/context_warning.cpython-311.pyc +0 -0
  249. package/pennyfarthing-dist/pf/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
  250. package/pennyfarthing-dist/pf/hooks/__pycache__/cyclist_pretooluse.cpython-311.pyc +0 -0
  251. package/pennyfarthing-dist/pf/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
  252. package/pennyfarthing-dist/pf/hooks/__pycache__/pre_edit_check.cpython-311.pyc +0 -0
  253. package/pennyfarthing-dist/pf/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
  254. package/pennyfarthing-dist/pf/hooks/__pycache__/reflector_check.cpython-311.pyc +0 -0
  255. package/pennyfarthing-dist/pf/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
  256. package/pennyfarthing-dist/pf/hooks/__pycache__/schema_validation.cpython-311.pyc +0 -0
  257. package/pennyfarthing-dist/pf/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
  258. package/pennyfarthing-dist/pf/hooks/__pycache__/session_start.cpython-311.pyc +0 -0
  259. package/pennyfarthing-dist/pf/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
  260. package/pennyfarthing-dist/pf/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
  261. package/pennyfarthing-dist/pf/hooks/__pycache__/sprint_yaml_validation.cpython-311.pyc +0 -0
  262. package/pennyfarthing-dist/pf/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
  263. package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-311.pyc +0 -0
  264. package/pennyfarthing-dist/pf/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
  265. package/pennyfarthing-dist/pf/hooks/statusline.py +11 -0
  266. package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-311.pyc +0 -0
  267. package/pennyfarthing-dist/pf/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  268. package/pennyfarthing-dist/pf/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  269. package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-311.pyc +0 -0
  270. package/pennyfarthing-dist/pf/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  271. package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-311.pyc +0 -0
  272. package/pennyfarthing-dist/pf/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  273. package/pennyfarthing-dist/pf/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  274. package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-311.pyc +0 -0
  275. package/pennyfarthing-dist/pf/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  276. package/pennyfarthing-dist/pf/jira/__init__.py +0 -6
  277. package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-311.pyc +0 -0
  278. package/pennyfarthing-dist/pf/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  279. package/pennyfarthing-dist/pf/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  280. package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-311.pyc +0 -0
  281. package/pennyfarthing-dist/pf/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  282. package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-311.pyc +0 -0
  283. package/pennyfarthing-dist/pf/jira/__pycache__/claim.cpython-314.pyc +0 -0
  284. package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-311.pyc +0 -0
  285. package/pennyfarthing-dist/pf/jira/__pycache__/cli.cpython-314.pyc +0 -0
  286. package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-311.pyc +0 -0
  287. package/pennyfarthing-dist/pf/jira/__pycache__/client.cpython-314.pyc +0 -0
  288. package/pennyfarthing-dist/pf/jira/__pycache__/compat.cpython-314.pyc +0 -0
  289. package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-311.pyc +0 -0
  290. package/pennyfarthing-dist/pf/jira/__pycache__/create.cpython-314.pyc +0 -0
  291. package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-311.pyc +0 -0
  292. package/pennyfarthing-dist/pf/jira/__pycache__/epic.cpython-314.pyc +0 -0
  293. package/pennyfarthing-dist/pf/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  294. package/pennyfarthing-dist/pf/jira/__pycache__/models.cpython-314.pyc +0 -0
  295. package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-311.pyc +0 -0
  296. package/pennyfarthing-dist/pf/jira/__pycache__/operations.cpython-314.pyc +0 -0
  297. package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-311.pyc +0 -0
  298. package/pennyfarthing-dist/pf/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  299. package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-311.pyc +0 -0
  300. package/pennyfarthing-dist/pf/jira/__pycache__/story.cpython-314.pyc +0 -0
  301. package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-311.pyc +0 -0
  302. package/pennyfarthing-dist/pf/jira/__pycache__/sync.cpython-314.pyc +0 -0
  303. package/pennyfarthing-dist/pf/jira/claim.py +14 -44
  304. package/pennyfarthing-dist/pf/jira/cli.py +124 -14
  305. package/pennyfarthing-dist/pf/jira/client.py +51 -87
  306. package/pennyfarthing-dist/pf/jira/reconcile.py +1 -1
  307. package/pennyfarthing-dist/pf/jira/story.py +6 -4
  308. package/pennyfarthing-dist/pf/jira/sync.py +2 -2
  309. package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-311.pyc +0 -0
  310. package/pennyfarthing-dist/pf/launch/__pycache__/__init__.cpython-314.pyc +0 -0
  311. package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-311.pyc +0 -0
  312. package/pennyfarthing-dist/pf/launch/__pycache__/cli.cpython-314.pyc +0 -0
  313. package/pennyfarthing-dist/pf/migration/__init__.py +1 -1
  314. package/pennyfarthing-dist/pf/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  315. package/pennyfarthing-dist/pf/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  316. package/pennyfarthing-dist/pf/migration/__pycache__/cli.cpython-314.pyc +0 -0
  317. package/pennyfarthing-dist/pf/migration/__pycache__/session.cpython-314.pyc +0 -0
  318. package/pennyfarthing-dist/pf/migration/__pycache__/skill.cpython-314.pyc +0 -0
  319. package/pennyfarthing-dist/pf/migration/__pycache__/step.cpython-314.pyc +0 -0
  320. package/pennyfarthing-dist/pf/migration/__pycache__/validate.cpython-314.pyc +0 -0
  321. package/pennyfarthing-dist/pf/migration/cli.py +0 -1
  322. package/pennyfarthing-dist/pf/package/__init__.py +0 -0
  323. package/pennyfarthing-dist/pf/package/__pycache__/__init__.cpython-314.pyc +0 -0
  324. package/pennyfarthing-dist/pf/package/__pycache__/cli.cpython-314.pyc +0 -0
  325. package/pennyfarthing-dist/pf/package/__pycache__/discovery.cpython-314.pyc +0 -0
  326. package/pennyfarthing-dist/pf/package/__pycache__/portraits.cpython-314.pyc +0 -0
  327. package/pennyfarthing-dist/pf/package/cli.py +186 -0
  328. package/pennyfarthing-dist/pf/package/discovery.py +130 -0
  329. package/pennyfarthing-dist/pf/package/portraits.py +243 -0
  330. package/pennyfarthing-dist/pf/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  331. package/pennyfarthing-dist/pf/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  332. package/pennyfarthing-dist/pf/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  333. package/pennyfarthing-dist/pf/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  334. package/pennyfarthing-dist/pf/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  335. package/pennyfarthing-dist/pf/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  336. package/pennyfarthing-dist/pf/prime/__pycache__/cli.cpython-314.pyc +0 -0
  337. package/pennyfarthing-dist/pf/prime/__pycache__/loader.cpython-314.pyc +0 -0
  338. package/pennyfarthing-dist/pf/prime/__pycache__/models.cpython-314.pyc +0 -0
  339. package/pennyfarthing-dist/pf/prime/__pycache__/persona.cpython-314.pyc +0 -0
  340. package/pennyfarthing-dist/pf/prime/__pycache__/session.cpython-314.pyc +0 -0
  341. package/pennyfarthing-dist/pf/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  342. package/pennyfarthing-dist/pf/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
  343. package/pennyfarthing-dist/pf/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  344. package/pennyfarthing-dist/pf/prime/loader.py +21 -7
  345. package/pennyfarthing-dist/pf/prime/workflow.py +11 -3
  346. package/pennyfarthing-dist/pf/release/__init__.py +0 -0
  347. package/pennyfarthing-dist/pf/release/__pycache__/__init__.cpython-314.pyc +0 -0
  348. package/pennyfarthing-dist/pf/release/__pycache__/cli.cpython-314.pyc +0 -0
  349. package/pennyfarthing-dist/pf/release/__pycache__/deprecate.cpython-314.pyc +0 -0
  350. package/pennyfarthing-dist/pf/release/__pycache__/dry_run.cpython-314.pyc +0 -0
  351. package/pennyfarthing-dist/pf/release/cli.py +112 -0
  352. package/pennyfarthing-dist/pf/release/deprecate.py +187 -0
  353. package/pennyfarthing-dist/pf/release/dry_run.py +187 -0
  354. package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-311.pyc +0 -0
  355. package/pennyfarthing-dist/pf/session/__pycache__/__init__.cpython-314.pyc +0 -0
  356. package/pennyfarthing-dist/pf/session/__pycache__/cli.cpython-311.pyc +0 -0
  357. package/pennyfarthing-dist/pf/session/__pycache__/cli.cpython-314.pyc +0 -0
  358. package/pennyfarthing-dist/pf/settings/__pycache__/__init__.cpython-314.pyc +0 -0
  359. package/pennyfarthing-dist/pf/settings/__pycache__/cli.cpython-314.pyc +0 -0
  360. package/pennyfarthing-dist/pf/settings/__pycache__/settings.cpython-314.pyc +0 -0
  361. package/pennyfarthing-dist/pf/sprint/__pycache__/__init__.cpython-311.pyc +0 -0
  362. package/pennyfarthing-dist/pf/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  363. package/pennyfarthing-dist/pf/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  364. package/pennyfarthing-dist/pf/sprint/__pycache__/archive.cpython-311.pyc +0 -0
  365. package/pennyfarthing-dist/pf/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  366. package/pennyfarthing-dist/pf/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  367. package/pennyfarthing-dist/pf/sprint/__pycache__/cli.cpython-311.pyc +0 -0
  368. package/pennyfarthing-dist/pf/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  369. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_add.cpython-311.pyc +0 -0
  370. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  371. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_update.cpython-311.pyc +0 -0
  372. package/pennyfarthing-dist/pf/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
  373. package/pennyfarthing-dist/pf/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  374. package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-311.pyc +0 -0
  375. package/pennyfarthing-dist/pf/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  376. package/pennyfarthing-dist/pf/sprint/__pycache__/shard_merge.cpython-314.pyc +0 -0
  377. package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-311.pyc +0 -0
  378. package/pennyfarthing-dist/pf/sprint/__pycache__/status.cpython-314.pyc +0 -0
  379. package/pennyfarthing-dist/pf/sprint/__pycache__/story_add.cpython-311.pyc +0 -0
  380. package/pennyfarthing-dist/pf/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  381. package/pennyfarthing-dist/pf/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  382. package/pennyfarthing-dist/pf/sprint/__pycache__/story_update.cpython-311.pyc +0 -0
  383. package/pennyfarthing-dist/pf/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  384. package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-311.pyc +0 -0
  385. package/pennyfarthing-dist/pf/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  386. package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-311.pyc +0 -0
  387. package/pennyfarthing-dist/pf/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  388. package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-311.pyc +0 -0
  389. package/pennyfarthing-dist/pf/sprint/__pycache__/work.cpython-314.pyc +0 -0
  390. package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-311.pyc +0 -0
  391. package/pennyfarthing-dist/pf/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  392. package/pennyfarthing-dist/pf/sprint/cli.py +1 -1
  393. package/pennyfarthing-dist/pf/sprint/loader.py +6 -74
  394. package/pennyfarthing-dist/pf/sprint/shard_merge.py +126 -0
  395. package/pennyfarthing-dist/pf/sprint/story_finish.py +4 -2
  396. package/pennyfarthing-dist/pf/sprint/yaml_io.py +8 -53
  397. package/pennyfarthing-dist/pf/story/__pycache__/__init__.cpython-314.pyc +0 -0
  398. package/pennyfarthing-dist/pf/story/__pycache__/__main__.cpython-314.pyc +0 -0
  399. package/pennyfarthing-dist/pf/story/__pycache__/cli.cpython-314.pyc +0 -0
  400. package/pennyfarthing-dist/pf/story/__pycache__/create.cpython-314.pyc +0 -0
  401. package/pennyfarthing-dist/pf/story/__pycache__/size.cpython-314.pyc +0 -0
  402. package/pennyfarthing-dist/pf/story/__pycache__/template.cpython-314.pyc +0 -0
  403. package/pennyfarthing-dist/pf/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  404. package/pennyfarthing-dist/pf/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  405. package/pennyfarthing-dist/pf/tests/__pycache__/test_108_1_gate_migration.cpython-314-pytest-9.0.2.pyc +0 -0
  406. package/pennyfarthing-dist/pf/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
  407. package/pennyfarthing-dist/pf/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
  408. package/pennyfarthing-dist/pf/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
  409. package/pennyfarthing-dist/pf/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  410. package/pennyfarthing-dist/pf/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  411. package/pennyfarthing-dist/pf/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
  412. package/pennyfarthing-dist/pf/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  413. package/pennyfarthing-dist/pf/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  414. package/pennyfarthing-dist/pf/tests/__pycache__/test_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
  415. package/pennyfarthing-dist/pf/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
  416. package/pennyfarthing-dist/pf/tests/__pycache__/test_dialogue_manager.cpython-314-pytest-9.0.2.pyc +0 -0
  417. package/pennyfarthing-dist/pf/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
  418. package/pennyfarthing-dist/pf/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  419. package/pennyfarthing-dist/pf/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  420. package/pennyfarthing-dist/pf/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  421. package/pennyfarthing-dist/pf/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  422. package/pennyfarthing-dist/pf/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  423. package/pennyfarthing-dist/pf/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  424. package/pennyfarthing-dist/pf/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  425. package/pennyfarthing-dist/pf/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  426. package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  427. package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
  428. package/pennyfarthing-dist/pf/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  429. package/pennyfarthing-dist/pf/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  430. package/pennyfarthing-dist/pf/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  431. package/pennyfarthing-dist/pf/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  432. package/pennyfarthing-dist/pf/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  433. package/pennyfarthing-dist/pf/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  434. package/pennyfarthing-dist/pf/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
  435. package/pennyfarthing-dist/pf/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
  436. package/pennyfarthing-dist/pf/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
  437. package/pennyfarthing-dist/pf/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  438. package/pennyfarthing-dist/pf/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
  439. package/pennyfarthing-dist/pf/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  440. package/pennyfarthing-dist/pf/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  441. package/pennyfarthing-dist/pf/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  442. package/pennyfarthing-dist/pf/tests/test_cli_modules.py +32 -137
  443. package/pennyfarthing-dist/pf/tests/test_codemarkers.py +0 -15
  444. package/pennyfarthing-dist/pf/tests/test_dist_root.py +720 -0
  445. package/pennyfarthing-dist/pf/tests/test_package_structure.py +24 -70
  446. package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-311.pyc +0 -0
  447. package/pennyfarthing-dist/pf/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  448. package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-311.pyc +0 -0
  449. package/pennyfarthing-dist/pf/theme/__pycache__/cli.cpython-314.pyc +0 -0
  450. package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-311.pyc +0 -0
  451. package/pennyfarthing-dist/pf/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  452. package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-311.pyc +0 -0
  453. package/pennyfarthing-dist/pf/validate/__pycache__/cli.cpython-314.pyc +0 -0
  454. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  455. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  456. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  457. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  458. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  459. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc +0 -0
  460. package/pennyfarthing-dist/pf/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  461. package/pennyfarthing-dist/pf/validate/adapters/agent.py +11 -1
  462. package/pennyfarthing-dist/pf/validate/adapters/skill_command.py +15 -4
  463. package/pennyfarthing-dist/pf/validate/adapters/tandem_awareness.py +7 -1
  464. package/pennyfarthing-dist/pf/validate/adapters/team_mode.py +8 -2
  465. package/pennyfarthing-dist/pf/validate/adapters/workflow.py +12 -2
  466. package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-311.pyc +0 -0
  467. package/pennyfarthing-dist/pf/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  468. package/pennyfarthing-dist/pf/workflow/__pycache__/cli.cpython-311.pyc +0 -0
  469. package/pennyfarthing-dist/pf/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  470. package/pennyfarthing-dist/pf/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  471. package/pennyfarthing-dist/pf/workflow/__pycache__/scale.cpython-311.pyc +0 -0
  472. package/pennyfarthing-dist/pf/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  473. package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-311.pyc +0 -0
  474. package/pennyfarthing-dist/pf/workflow/__pycache__/state.cpython-314.pyc +0 -0
  475. package/pennyfarthing-dist/pyproject.toml +1 -1
  476. package/pennyfarthing-dist/scripts/core/check-context.sh +2 -2
  477. package/pennyfarthing-dist/scripts/git/changelog-links.sh +216 -0
  478. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  479. package/pennyfarthing-dist/scripts/lib/README.md +0 -1
  480. package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +54 -0
  481. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +7 -3
  482. package/pennyfarthing-dist/workflows/patch.yaml +5 -6
  483. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +12 -0
  484. package/packages/core/dist/workflow/team-lifecycle.d.ts +0 -169
  485. package/packages/core/dist/workflow/team-lifecycle.d.ts.map +0 -1
  486. package/packages/core/dist/workflow/team-lifecycle.js +0 -217
  487. package/packages/core/dist/workflow/team-lifecycle.js.map +0 -1
  488. package/packages/core/dist/workflow/team-lifecycle.test.d.ts +0 -20
  489. package/packages/core/dist/workflow/team-lifecycle.test.d.ts.map +0 -1
  490. package/packages/core/dist/workflow/team-lifecycle.test.js +0 -966
  491. package/packages/core/dist/workflow/team-lifecycle.test.js.map +0 -1
  492. package/packages/core/src/public/components/FontPicker/FontPicker.css +0 -276
  493. package/packages/core/src/public/components/FontPicker/index.tsx +0 -430
  494. package/packages/core/src/public/components/ThemePalette/ThemePalette.css +0 -179
  495. package/packages/core/src/public/components/ThemePalette/index.tsx +0 -326
  496. package/packages/core/src/public/components/panels/BackgroundPanel.tsx +0 -115
  497. package/packages/core/src/public/components/ui/switch.tsx +0 -27
  498. package/packages/core/src/public/hooks/useBackgroundTasks.ts +0 -131
  499. package/pennyfarthing-dist/pf/bikerack/background_panel.py +0 -162
  500. package/pennyfarthing-dist/pf/bmad/__pycache__/parser.cpython-314.pyc +0 -0
  501. package/pennyfarthing-dist/pf/brownfield/__main__.py +0 -8
  502. package/pennyfarthing-dist/pf/config.py +0 -21
  503. package/pennyfarthing-dist/pf/hooks.py +0 -32
  504. package/pennyfarthing-dist/pf/jira_bidirectional_sync.py +0 -37
  505. package/pennyfarthing-dist/pf/jira_epic_creation.py +0 -30
  506. package/pennyfarthing-dist/pf/jira_sync.py +0 -36
  507. package/pennyfarthing-dist/pf/jira_sync_story.py +0 -30
  508. package/pennyfarthing-dist/pf/migration/__main__.py +0 -10
  509. package/pennyfarthing-dist/pf/output.py +0 -37
  510. package/pennyfarthing-dist/pf/theme/__main__.py +0 -6
  511. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -177
@@ -41,6 +41,16 @@ def _extract_agent_slug(theme_yaml: Path, agent: str) -> str | None:
41
41
  return None
42
42
 
43
43
 
44
+ def _is_lfs_pointer(path: Path) -> bool:
45
+ """Check if a file is a git-lfs pointer instead of actual image data."""
46
+ try:
47
+ with open(path, "rb") as f:
48
+ header = f.read(44)
49
+ return header.startswith(b"version https://git-lfs")
50
+ except OSError:
51
+ return False
52
+
53
+
44
54
  def _find_portrait(portraits_theme_dir: Path, slug: str) -> Path | None:
45
55
  """Find a portrait file matching the slug in a theme's portrait directory."""
46
56
  if not portraits_theme_dir.is_dir():
@@ -50,11 +60,13 @@ def _find_portrait(portraits_theme_dir: Path, slug: str) -> Path | None:
50
60
  if size_dir.is_dir():
51
61
  for f in size_dir.iterdir():
52
62
  if f.name.lower().startswith(slug.lower()) and f.suffix in (".png", ".jpg"):
53
- return f
63
+ if not _is_lfs_pointer(f):
64
+ return f
54
65
  # Fallback to root of theme dir
55
66
  for f in portraits_theme_dir.iterdir():
56
67
  if f.is_file() and f.name.lower().startswith(slug.lower()) and f.suffix in (".png", ".jpg"):
57
- return f
68
+ if not _is_lfs_pointer(f):
69
+ return f
58
70
  return None
59
71
 
60
72
 
@@ -3,6 +3,8 @@
3
3
  Combines story context, workflow phase, acceptance criteria, todos, and
4
4
  git status into a single at-a-glance panel. Subscribes to 4 WS channels:
5
5
  /ws/story, /ws/todos, /ws/git, /ws/sprint.
6
+
7
+ Story 120-8: Added Enter keybinding for story detail drill-through.
6
8
  """
7
9
 
8
10
  from __future__ import annotations
@@ -11,6 +13,7 @@ from typing import Any
11
13
 
12
14
  from rich.console import Group
13
15
  from rich.text import Text
16
+ from textual.binding import Binding
14
17
 
15
18
  from pf.bikerack.base_panel import (
16
19
  PANEL_ICONS,
@@ -31,6 +34,10 @@ class ProgressPanel(BasePanel):
31
34
  panel_name: str = "Progress"
32
35
  icon: str = PANEL_ICONS.get("progress", ("\uf200", "P"))[0]
33
36
 
37
+ BINDINGS = [
38
+ Binding("enter", "drill_detail", "Story Details", show=False),
39
+ ]
40
+
34
41
  def __init__(self, client: Any = None, **kwargs: Any) -> None:
35
42
  super().__init__(client=client, **kwargs)
36
43
  self._story_data: dict[str, Any] | None = None
@@ -79,6 +86,49 @@ class ProgressPanel(BasePanel):
79
86
  except Exception:
80
87
  pass
81
88
 
89
+ def drill_into_story(self) -> None:
90
+ """Push StoryDetailScreen for the current story."""
91
+ story_data = self._build_story_detail_data()
92
+ if story_data is None:
93
+ return
94
+ from pf.bikerack.story_detail_screen import StoryDetailScreen
95
+
96
+ try:
97
+ self.app.push_screen(StoryDetailScreen(story_data=story_data))
98
+ except Exception:
99
+ pass
100
+
101
+ def action_drill_detail(self) -> None:
102
+ """Action handler for Enter keybinding — drill into story details."""
103
+ self.drill_into_story()
104
+
105
+ def _build_story_detail_data(self) -> dict[str, Any] | None:
106
+ """Build story_data dict suitable for StoryDetailScreen."""
107
+ story = self._story_data or {}
108
+ sprint = self._sprint_data or {}
109
+
110
+ current = sprint.get("sprint", {}).get("currentStory")
111
+ if isinstance(current, str) and current:
112
+ story_id = current
113
+ else:
114
+ story_id = story.get("id", "")
115
+
116
+ if not story_id and not story.get("title"):
117
+ return None
118
+
119
+ return {
120
+ "id": story_id,
121
+ "title": story.get("title", ""),
122
+ "points": story.get("points", ""),
123
+ "status": story.get("status", ""),
124
+ "assignee": story.get("assignee", ""),
125
+ "workflow": story.get("workflow", ""),
126
+ "workflow_phase": story.get("phase", ""),
127
+ **{k: v for k, v in story.items() if k not in (
128
+ "id", "title", "points", "status", "assignee", "workflow", "phase",
129
+ )},
130
+ }
131
+
82
132
  def render_panel(self, payload: dict[str, Any]) -> Any:
83
133
  """Render unified progress view."""
84
134
  parts: list[Any] = []
@@ -116,6 +166,10 @@ class ProgressPanel(BasePanel):
116
166
  if git is not None:
117
167
  parts.append(git)
118
168
 
169
+ # --- Drill-through hint ---
170
+ parts.append(Text(""))
171
+ parts.append(Text("[Enter] Story Details", style="dim"))
172
+
119
173
  return Group(*parts)
120
174
 
121
175
  def _render_story_header(self) -> Text | None:
@@ -280,6 +280,16 @@ class SprintPanel(Widget):
280
280
  f"In Progress: {in_progress} | "
281
281
  f"Velocity: {velocity}"
282
282
  )
283
+ registry = payload.get("registry")
284
+ if registry and not registry.get("isDefault", True):
285
+ reg_type = registry.get("type", "")
286
+ reg_name = registry.get("name", "")
287
+ if reg_type and reg_name:
288
+ header_text.append(f" [{reg_type}:{reg_name}]")
289
+ elif reg_name:
290
+ header_text.append(f" [{reg_name}]")
291
+ elif reg_type:
292
+ header_text.append(f" [{reg_type}]")
283
293
  try:
284
294
  self.query_one("#sprint-header", Static).update(header_text)
285
295
  except Exception:
@@ -356,6 +366,54 @@ class SprintPanel(Widget):
356
366
  if cursor_node_key == f"epic:{epic_id}":
357
367
  cursor_target = epic_node
358
368
 
369
+ # Completed Epics section (Story 110-6)
370
+ completed_epics = payload.get("completedEpics", [])
371
+ if completed_epics:
372
+ separator_label = Text("── Completed ──", style="bold dim")
373
+ tree.root.add_leaf(separator_label, data={"type": "separator"})
374
+
375
+ for epic in completed_epics:
376
+ epic_id = epic.get("id", "")
377
+ epic_title = epic.get("title", "")
378
+ stories = epic.get("stories", [])
379
+
380
+ total_pts = 0
381
+ done_pts = 0
382
+ for story in stories:
383
+ pts = story.get("points", 0)
384
+ if isinstance(pts, (int, float)):
385
+ total_pts += pts
386
+ if _is_terminal(story.get("status", "")):
387
+ done_pts += pts
388
+
389
+ label = _build_epic_label(
390
+ epic_id, epic_title, done_pts, total_pts,
391
+ jira_key=epic.get("jiraKey", ""),
392
+ )
393
+ epic_data: dict[str, Any] = {
394
+ "type": "epic",
395
+ "id": epic_id,
396
+ "title": epic_title,
397
+ }
398
+ epic_node = tree.root.add(label, data=epic_data)
399
+
400
+ for story in stories:
401
+ story_label = _build_story_label(story, current_story_id)
402
+ story_data: dict[str, Any] = {"type": "story", "story": story}
403
+ epic_node.add_leaf(story_label, data=story_data)
404
+
405
+ # Completed epics: collapsed by default, respect saved state
406
+ if epic_id in saved_expanded:
407
+ if saved_expanded[epic_id]:
408
+ epic_node.expand()
409
+ else:
410
+ epic_node.collapse()
411
+ else:
412
+ epic_node.collapse()
413
+
414
+ if cursor_node_key == f"epic:{epic_id}":
415
+ cursor_target = epic_node
416
+
359
417
  # Future Initiatives section (Story 118-1)
360
418
  future_epics = payload.get("futureEpics", [])
361
419
  if future_epics:
@@ -1,7 +1,8 @@
1
1
  """StoryDetailScreen — Mission dossier detail view for BikeRack TUI.
2
2
 
3
3
  Story 110-2: Story drill-through with dossier detail screen.
4
- Pushed via Screen.push() from SprintPanel when user presses Enter on a story.
4
+ Story 120-8: Upgraded to use StoryDetailWidget with native Textual widgets.
5
+ Pushed via Screen.push() from SprintPanel or ProgressPanel.
5
6
  """
6
7
 
7
8
  from __future__ import annotations
@@ -9,17 +10,17 @@ from __future__ import annotations
9
10
  import webbrowser
10
11
  from typing import Any
11
12
 
12
- from rich.text import Text
13
13
  from textual.binding import Binding
14
+ from textual.containers import VerticalScroll
14
15
  from textual.screen import Screen
15
- from textual.widgets import Static
16
+
17
+ from pf.bikerack.story_detail_widget import StoryDetailWidget
16
18
 
17
19
 
18
20
  class StoryDetailScreen(Screen):
19
21
  """Detail screen showing story dossier layout.
20
22
 
21
- Displays AC checklist, workflow phase dots, git branch, PR link,
22
- and session notes in a mission-dossier layout.
23
+ Delegates rendering to StoryDetailWidget inside a VerticalScroll.
23
24
  """
24
25
 
25
26
  BINDINGS = [
@@ -57,107 +58,11 @@ class StoryDetailScreen(Screen):
57
58
  return merged
58
59
 
59
60
  def compose(self):
60
- """Compose the dossier layout with header, ACs, workflow, git info.
61
-
62
- Absent sections are simply omitted (Tufte: absence is information).
63
- """
64
- data = self._story_data
65
-
66
- # Header section
67
- title = data.get("title", "Unknown Story")
68
- points = data.get("points", "?")
69
- status = data.get("status", "unknown")
70
- jira_key = data.get("jiraKey", "")
71
- assignee = data.get("assignee", "")
72
- priority = data.get("priority", "")
73
-
74
- header_text = Text()
75
- if jira_key:
76
- header_text.append(f"{jira_key}", style="bold cyan")
77
- header_text.append(" ")
78
- header_text.append(f"{title}", style="bold")
79
- # Metadata line
80
- meta_parts = [status]
81
- if points and points != "?":
82
- meta_parts.append(f"{points} pts")
83
- if priority:
84
- meta_parts.append(priority)
85
- if assignee:
86
- from pf.bikerack.sprint_panel import _format_assignee
87
-
88
- name = _format_assignee(assignee)
89
- if name:
90
- meta_parts.append(name)
91
- separator = " \u00b7 "
92
- header_text.append(f"\n{separator.join(meta_parts)}", style="dim")
93
- yield Static(header_text, id="dossier-header")
94
-
95
- # Context section (only if context files exist)
96
- has_epic_ctx = data.get("has_epic_context", False)
97
- has_story_ctx = data.get("has_story_context", False)
98
- if has_epic_ctx or has_story_ctx:
99
- ctx_text = Text()
100
- ctx_text.append("Context\n", style="bold underline")
101
- if has_epic_ctx:
102
- ctx_text.append(" \u2713 Epic context\n", style="green")
103
- else:
104
- ctx_text.append(" \u25cb Epic context\n", style="dim")
105
- if has_story_ctx:
106
- ctx_text.append(" \u2713 Story context\n", style="green")
107
- else:
108
- ctx_text.append(" \u25cb Story context\n", style="dim")
109
- yield Static(ctx_text, id="dossier-context")
110
-
111
- # Acceptance Criteria section
112
- acs = data.get("acceptance_criteria", [])
113
- if acs:
114
- ac_text = Text()
115
- done_count = sum(1 for ac in acs if ac.get("done"))
116
- ac_text.append("Acceptance Criteria", style="bold underline")
117
- ac_text.append(f" {done_count}/{len(acs)}\n", style="dim")
118
- for ac in acs:
119
- check = "\u2713" if ac.get("done") else "\u25cb"
120
- style = "green" if ac.get("done") else ""
121
- ac_text.append(f" {check} {ac.get('text', '')}\n", style=style)
122
- yield Static(ac_text, id="dossier-ac")
123
-
124
- # Workflow section
125
- workflow = data.get("workflow", "")
126
- phase = data.get("workflow_phase", "")
127
- if workflow:
128
- wf_text = Text()
129
- wf_text.append("Workflow\n", style="bold underline")
130
- wf_text.append(f" {workflow}", style="cyan")
131
- if phase:
132
- wf_text.append(f" Phase: {phase}", style="yellow")
133
- wf_text.append("\n")
134
- yield Static(wf_text, id="dossier-workflow")
135
-
136
- # Git info section
137
- branch = data.get("git_branch", "")
138
- pr_url = data.get("pr_url")
139
- if branch or pr_url:
140
- git_text = Text()
141
- git_text.append("Git\n", style="bold underline")
142
- if branch:
143
- git_text.append(f" Branch: {branch}\n")
144
- if pr_url:
145
- git_text.append(f" PR: {pr_url}\n", style="cyan")
146
- yield Static(git_text, id="dossier-git")
147
-
148
- # Session notes section
149
- notes = data.get("session_notes", "")
150
- if notes:
151
- notes_text = Text()
152
- notes_text.append("Session Notes\n", style="bold underline")
153
- notes_text.append(f" {notes}\n")
154
- yield Static(notes_text, id="dossier-notes")
155
-
156
- # Keybinding hint
157
- hint = Text.from_markup(
158
- "\n[dim][Escape] Back [Enter] Open PR[/dim]"
61
+ """Compose the dossier layout using StoryDetailWidget."""
62
+ yield VerticalScroll(
63
+ StoryDetailWidget(story_data=self._story_data),
64
+ id="detail-scroll",
159
65
  )
160
- yield Static(hint, id="dossier-hint")
161
66
 
162
67
  def action_pop_screen(self) -> None:
163
68
  """Pop this screen off the stack."""
@@ -0,0 +1,167 @@
1
+ """StoryDetailWidget — Reusable story detail view using native Textual widgets.
2
+
3
+ Story 120-8: Story details and progress page enrichment with native Textual widgets.
4
+ Renders story data inside Collapsible sections with Rule separators.
5
+ Used by both StoryDetailScreen and ProgressPanel drill-through.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+
12
+ from rich.text import Text
13
+ from textual.widget import Widget
14
+ from textual.widgets import Collapsible, Rule, Static
15
+
16
+
17
+ class StoryDetailWidget(Widget):
18
+ """Reusable story detail view with native Textual widgets.
19
+
20
+ Renders story data as Collapsible sections for ACs, Workflow, Git,
21
+ Context, and Session Notes. Absent sections are omitted (Tufte pattern).
22
+ """
23
+
24
+ def __init__(self, story_data: dict[str, Any] | None = None, **kwargs: Any) -> None:
25
+ super().__init__(**kwargs)
26
+ self._story_data: dict[str, Any] = story_data or {}
27
+
28
+ def compose(self):
29
+ """Compose the detail layout with header and collapsible sections."""
30
+ data = self._story_data
31
+
32
+ # Header — always present
33
+ yield self._build_header(data)
34
+
35
+ # Sections — only yielded when data exists
36
+ sections_yielded = 0
37
+
38
+ # Acceptance Criteria
39
+ acs = data.get("acceptance_criteria", [])
40
+ if acs:
41
+ if sections_yielded > 0:
42
+ yield Rule()
43
+ done_count = sum(1 for ac in acs if ac.get("done"))
44
+ yield self._build_ac_section(acs, done_count)
45
+ sections_yielded += 1
46
+
47
+ # Workflow
48
+ workflow = data.get("workflow", "")
49
+ if workflow:
50
+ if sections_yielded > 0:
51
+ yield Rule()
52
+ phase = data.get("workflow_phase", "")
53
+ yield self._build_workflow_section(workflow, phase)
54
+ sections_yielded += 1
55
+
56
+ # Git
57
+ branch = data.get("git_branch", "")
58
+ pr_url = data.get("pr_url")
59
+ if branch or pr_url:
60
+ if sections_yielded > 0:
61
+ yield Rule()
62
+ yield self._build_git_section(branch, pr_url)
63
+ sections_yielded += 1
64
+
65
+ # Context
66
+ has_epic_ctx = data.get("has_epic_context", False)
67
+ has_story_ctx = data.get("has_story_context", False)
68
+ if has_epic_ctx or has_story_ctx:
69
+ if sections_yielded > 0:
70
+ yield Rule()
71
+ yield self._build_context_section(has_epic_ctx, has_story_ctx)
72
+ sections_yielded += 1
73
+
74
+ # Session Notes
75
+ notes = data.get("session_notes", "")
76
+ if notes:
77
+ if sections_yielded > 0:
78
+ yield Rule()
79
+ yield self._build_notes_section(notes)
80
+ sections_yielded += 1
81
+
82
+ @staticmethod
83
+ def _build_header(data: dict[str, Any]) -> Static:
84
+ """Build the story header with title and metadata."""
85
+ title = data.get("title", "Unknown Story")
86
+ points = data.get("points", "?")
87
+ status = data.get("status", "unknown")
88
+ jira_key = data.get("jiraKey", "")
89
+ assignee = data.get("assignee", "")
90
+ priority = data.get("priority", "")
91
+
92
+ header_text = Text()
93
+ if jira_key:
94
+ header_text.append(f"{jira_key}", style="bold cyan")
95
+ header_text.append(" ")
96
+ header_text.append(f"{title}", style="bold")
97
+ if points and points != "?":
98
+ header_text.append(f" {points}pt", style="dim")
99
+
100
+ meta_parts = [status]
101
+ if priority:
102
+ meta_parts.append(priority)
103
+ if assignee:
104
+ meta_parts.append(assignee)
105
+ separator = " \u00b7 "
106
+ header_text.append(f"\n{separator.join(meta_parts)}", style="dim")
107
+
108
+ return Static(header_text, id="detail-header")
109
+
110
+ @staticmethod
111
+ def _build_ac_section(
112
+ acs: list[dict[str, Any]], done_count: int
113
+ ) -> Collapsible:
114
+ """Build the Acceptance Criteria collapsible section."""
115
+ ac_text = Text()
116
+ for ac in acs:
117
+ check = "\u2713" if ac.get("done") else "\u25cb"
118
+ style = "green" if ac.get("done") else ""
119
+ ac_text.append(f" {check} {ac.get('text', '')}\n", style=style)
120
+
121
+ return Collapsible(
122
+ Static(ac_text),
123
+ title=f"Acceptance Criteria {done_count}/{len(acs)}",
124
+ )
125
+
126
+ @staticmethod
127
+ def _build_workflow_section(workflow: str, phase: str) -> Collapsible:
128
+ """Build the Workflow collapsible section."""
129
+ wf_text = Text()
130
+ wf_text.append(f" [{workflow}]", style="cyan")
131
+ if phase:
132
+ wf_text.append(f" Phase: {phase}", style="yellow")
133
+
134
+ return Collapsible(Static(wf_text), title="Workflow")
135
+
136
+ @staticmethod
137
+ def _build_git_section(branch: str, pr_url: str | None) -> Collapsible:
138
+ """Build the Git collapsible section."""
139
+ git_text = Text()
140
+ if branch:
141
+ git_text.append(f" Branch: {branch}\n")
142
+ if pr_url:
143
+ git_text.append(f" PR: {pr_url}\n", style="cyan")
144
+
145
+ return Collapsible(Static(git_text), title="Git")
146
+
147
+ @staticmethod
148
+ def _build_context_section(
149
+ has_epic: bool, has_story: bool
150
+ ) -> Collapsible:
151
+ """Build the Context collapsible section."""
152
+ ctx_text = Text()
153
+ if has_epic:
154
+ ctx_text.append(" \u2713 Epic context\n", style="green")
155
+ else:
156
+ ctx_text.append(" \u25cb Epic context\n", style="dim")
157
+ if has_story:
158
+ ctx_text.append(" \u2713 Story context\n", style="green")
159
+ else:
160
+ ctx_text.append(" \u25cb Story context\n", style="dim")
161
+
162
+ return Collapsible(Static(ctx_text), title="Context")
163
+
164
+ @staticmethod
165
+ def _build_notes_section(notes: str) -> Collapsible:
166
+ """Build the Session Notes collapsible section."""
167
+ return Collapsible(Static(f" {notes}"), title="Session Notes")