@pennyfarthing/core 10.1.0 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/README.md +13 -18
  2. package/package.json +3 -1
  3. package/packages/core/dist/cli/commands/doctor-file-layout.test.js.map +1 -1
  4. package/packages/core/dist/cli/commands/doctor-legacy.test.js +24 -0
  5. package/packages/core/dist/cli/commands/doctor-legacy.test.js.map +1 -1
  6. package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
  7. package/packages/core/dist/cli/commands/doctor.js +101 -15
  8. package/packages/core/dist/cli/commands/doctor.js.map +1 -1
  9. package/packages/core/dist/cli/commands/e2e-fresh-install.test.js +1 -1
  10. package/packages/core/dist/cli/commands/e2e-fresh-install.test.js.map +1 -1
  11. package/packages/core/dist/cli/commands/e2e-upgrade.test.js +1 -1
  12. package/packages/core/dist/cli/commands/e2e-upgrade.test.js.map +1 -1
  13. package/packages/core/dist/cli/commands/hooks-consolidation.test.js +2 -2
  14. package/packages/core/dist/cli/commands/hooks-consolidation.test.js.map +1 -1
  15. package/packages/core/dist/cli/commands/init-consolidation.test.js.map +1 -1
  16. package/packages/core/dist/cli/commands/uninstall.d.ts.map +1 -1
  17. package/packages/core/dist/cli/commands/uninstall.js +24 -13
  18. package/packages/core/dist/cli/commands/uninstall.js.map +1 -1
  19. package/packages/core/dist/cli/commands/update-consolidation.test.js +0 -10
  20. package/packages/core/dist/cli/commands/update-consolidation.test.js.map +1 -1
  21. package/packages/core/dist/cli/commands/update.js.map +1 -1
  22. package/packages/core/dist/cli/ocean-profiles.test.js.map +1 -1
  23. package/packages/core/dist/cli/theme-maker.test.js +64 -115
  24. package/packages/core/dist/cli/theme-maker.test.js.map +1 -1
  25. package/packages/core/dist/index.d.ts +1 -1
  26. package/packages/core/dist/index.d.ts.map +1 -1
  27. package/packages/core/dist/index.js +2 -2
  28. package/packages/core/dist/index.js.map +1 -1
  29. package/packages/core/dist/plugins/plugin-discovery.d.ts +116 -0
  30. package/packages/core/dist/plugins/plugin-discovery.d.ts.map +1 -0
  31. package/packages/core/dist/plugins/plugin-discovery.js +165 -0
  32. package/packages/core/dist/plugins/plugin-discovery.js.map +1 -0
  33. package/packages/core/dist/plugins/plugin-discovery.test.d.ts +22 -0
  34. package/packages/core/dist/plugins/plugin-discovery.test.d.ts.map +1 -0
  35. package/packages/core/dist/plugins/plugin-discovery.test.js +498 -0
  36. package/packages/core/dist/plugins/plugin-discovery.test.js.map +1 -0
  37. package/packages/core/dist/scripts/generate-spider-report.js.map +1 -1
  38. package/packages/core/dist/workflow/context-watch.d.ts +80 -0
  39. package/packages/core/dist/workflow/context-watch.d.ts.map +1 -0
  40. package/packages/core/dist/workflow/context-watch.js +235 -0
  41. package/packages/core/dist/workflow/context-watch.js.map +1 -0
  42. package/packages/core/dist/workflow/context-watch.test.d.ts +1 -0
  43. package/packages/core/dist/workflow/context-watch.test.d.ts.map +1 -0
  44. package/packages/core/dist/workflow/context-watch.test.js +746 -0
  45. package/packages/core/dist/workflow/context-watch.test.js.map +1 -0
  46. package/packages/core/dist/workflow/file-watch.d.ts +82 -0
  47. package/packages/core/dist/workflow/file-watch.d.ts.map +1 -0
  48. package/packages/core/dist/workflow/file-watch.js +198 -0
  49. package/packages/core/dist/workflow/file-watch.js.map +1 -0
  50. package/packages/core/dist/workflow/file-watch.test.d.ts +21 -0
  51. package/packages/core/dist/workflow/file-watch.test.d.ts.map +1 -0
  52. package/packages/core/dist/workflow/file-watch.test.js +469 -0
  53. package/packages/core/dist/workflow/file-watch.test.js.map +1 -0
  54. package/packages/core/dist/workflow/observation-writer.d.ts +79 -0
  55. package/packages/core/dist/workflow/observation-writer.d.ts.map +1 -0
  56. package/packages/core/dist/workflow/observation-writer.js +97 -0
  57. package/packages/core/dist/workflow/observation-writer.js.map +1 -0
  58. package/packages/core/dist/workflow/observation-writer.test.d.ts +18 -0
  59. package/packages/core/dist/workflow/observation-writer.test.d.ts.map +1 -0
  60. package/packages/core/dist/workflow/observation-writer.test.js +424 -0
  61. package/packages/core/dist/workflow/observation-writer.test.js.map +1 -0
  62. package/packages/core/dist/workflow/story-workflow-routing.test.js +4 -2
  63. package/packages/core/dist/workflow/story-workflow-routing.test.js.map +1 -1
  64. package/packages/core/dist/workflow/tandem-lifecycle.d.ts +117 -0
  65. package/packages/core/dist/workflow/tandem-lifecycle.d.ts.map +1 -0
  66. package/packages/core/dist/workflow/tandem-lifecycle.js +186 -0
  67. package/packages/core/dist/workflow/tandem-lifecycle.js.map +1 -0
  68. package/packages/core/dist/workflow/tandem-lifecycle.test.d.ts +16 -0
  69. package/packages/core/dist/workflow/tandem-lifecycle.test.d.ts.map +1 -0
  70. package/packages/core/dist/workflow/tandem-lifecycle.test.js +531 -0
  71. package/packages/core/dist/workflow/tandem-lifecycle.test.js.map +1 -0
  72. package/packages/core/dist/workflow/tool-watch.d.ts +68 -0
  73. package/packages/core/dist/workflow/tool-watch.d.ts.map +1 -0
  74. package/packages/core/dist/workflow/tool-watch.js +166 -0
  75. package/packages/core/dist/workflow/tool-watch.js.map +1 -0
  76. package/packages/core/dist/workflow/tool-watch.test.d.ts +18 -0
  77. package/packages/core/dist/workflow/tool-watch.test.d.ts.map +1 -0
  78. package/packages/core/dist/workflow/tool-watch.test.js +718 -0
  79. package/packages/core/dist/workflow/tool-watch.test.js.map +1 -0
  80. package/packages/core/dist/workflow/workflow-migration.test.js +8 -4
  81. package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -1
  82. package/packages/core/dist/workflow/workflow-schema.d.ts +7 -0
  83. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
  84. package/packages/core/dist/workflow/workflow-schema.js +44 -0
  85. package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
  86. package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -1
  87. package/packages/core/dist/workflow/workflow-schema.test.js +192 -0
  88. package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -1
  89. package/pennyfarthing-dist/agents/handoff.md +18 -3
  90. package/pennyfarthing-dist/agents/sm-finish.md +1 -1
  91. package/pennyfarthing-dist/agents/sm-handoff.md +27 -4
  92. package/pennyfarthing-dist/agents/sm.md +11 -5
  93. package/pennyfarthing-dist/agents/tandem-backseat.md +119 -0
  94. package/pennyfarthing-dist/commands/setup.md +4 -0
  95. package/pennyfarthing-dist/guides/agent-behavior.md +62 -6
  96. package/pennyfarthing-dist/guides/bikelane.md +3 -2
  97. package/pennyfarthing-dist/guides/scale-levels.md +4 -6
  98. package/pennyfarthing-dist/guides/tandem-protocol.md +158 -0
  99. package/pennyfarthing-dist/personas/themes/discworld.yaml +1 -1
  100. package/pennyfarthing-dist/personas/themes/fifth-element.yaml +295 -0
  101. package/pennyfarthing-dist/scripts/README.md +1 -1
  102. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +131 -54
  103. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +20 -10
  104. package/pennyfarthing-dist/scripts/misc/statusline.sh +50 -8
  105. package/pennyfarthing-dist/scripts/workflow/README.md +2 -2
  106. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +10 -189
  107. package/pennyfarthing-dist/skills/skill-registry.schema.json +8 -0
  108. package/pennyfarthing-dist/skills/skill-registry.yaml +1 -1
  109. package/pennyfarthing-dist/skills/sprint/skill.md +25 -2
  110. package/pennyfarthing-dist/skills/workflow/skill.md +24 -1
  111. package/pennyfarthing-dist/workflows/architecture/workflow.yaml +65 -0
  112. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +70 -0
  113. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +61 -0
  114. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  115. package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  116. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  117. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  118. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  119. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  120. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  121. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  122. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  123. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  124. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  125. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  126. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  127. package/pennyfarthing_scripts/bellmode_hook.py +202 -47
  128. package/pennyfarthing_scripts/brownfield/__init__.py +6 -6
  129. package/pennyfarthing_scripts/brownfield/__main__.py +1 -0
  130. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  131. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  132. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  133. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  134. package/pennyfarthing_scripts/brownfield/cli.py +0 -1
  135. package/pennyfarthing_scripts/brownfield/discover.py +1 -2
  136. package/pennyfarthing_scripts/cli.py +11 -6
  137. package/pennyfarthing_scripts/codemarkers/__init__.py +5 -1
  138. package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  139. package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  140. package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  141. package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  142. package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  143. package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  144. package/pennyfarthing_scripts/codemarkers/analyze.py +177 -2
  145. package/pennyfarthing_scripts/codemarkers/cli.py +50 -0
  146. package/pennyfarthing_scripts/codemarkers/formatters.py +0 -1
  147. package/pennyfarthing_scripts/codemarkers/models.py +15 -0
  148. package/pennyfarthing_scripts/common/__init__.py +8 -9
  149. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  150. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  151. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  152. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  153. package/pennyfarthing_scripts/common/config.py +1 -1
  154. package/pennyfarthing_scripts/complexity/__init__.py +1 -1
  155. package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  156. package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  157. package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  158. package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  159. package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  160. package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
  161. package/pennyfarthing_scripts/complexity/analyze.py +1 -1
  162. package/pennyfarthing_scripts/complexity/cli.py +5 -1
  163. package/pennyfarthing_scripts/complexity/formatters.py +1 -1
  164. package/pennyfarthing_scripts/context.py +14 -15
  165. package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  166. package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  167. package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  168. package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  169. package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  170. package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  171. package/pennyfarthing_scripts/deadcode/analyze.py +3 -4
  172. package/pennyfarthing_scripts/deadcode/cli.py +2 -2
  173. package/pennyfarthing_scripts/dependencies/__init__.py +2 -2
  174. package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  175. package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  176. package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  177. package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  178. package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  179. package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  180. package/pennyfarthing_scripts/dependencies/analyze.py +1 -1
  181. package/pennyfarthing_scripts/dependencies/cli.py +8 -4
  182. package/pennyfarthing_scripts/dependencies/formatters.py +1 -1
  183. package/pennyfarthing_scripts/git/__init__.py +5 -5
  184. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  185. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  186. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  187. package/pennyfarthing_scripts/git/create_branches.py +3 -2
  188. package/pennyfarthing_scripts/git/status_all.py +1 -1
  189. package/pennyfarthing_scripts/healthscore/__init__.py +2 -2
  190. package/pennyfarthing_scripts/healthscore/__main__.py +8 -0
  191. package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  192. package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  193. package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  194. package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  195. package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  196. package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  197. package/pennyfarthing_scripts/healthscore/analyze.py +451 -21
  198. package/pennyfarthing_scripts/healthscore/cli.py +5 -1
  199. package/pennyfarthing_scripts/healthscore/models.py +0 -1
  200. package/pennyfarthing_scripts/hooks.py +8 -11
  201. package/pennyfarthing_scripts/hotspots/__init__.py +6 -6
  202. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  203. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  204. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  206. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/hotspots/analyze.py +128 -14
  209. package/pennyfarthing_scripts/hotspots/cli.py +2 -2
  210. package/pennyfarthing_scripts/hotspots/models.py +0 -1
  211. package/pennyfarthing_scripts/jira/__init__.py +15 -17
  212. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  213. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  214. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  215. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  216. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  217. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  218. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  219. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  220. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  221. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  222. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  223. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/jira/bidirectional.py +2 -3
  225. package/pennyfarthing_scripts/jira/claim.py +21 -0
  226. package/pennyfarthing_scripts/jira/cli.py +2 -2
  227. package/pennyfarthing_scripts/jira/client.py +4 -4
  228. package/pennyfarthing_scripts/jira/create.py +45 -1
  229. package/pennyfarthing_scripts/jira/epic.py +3 -2
  230. package/pennyfarthing_scripts/jira/reconcile.py +0 -1
  231. package/pennyfarthing_scripts/jira/story.py +2 -0
  232. package/pennyfarthing_scripts/jira/sync.py +1 -1
  233. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  235. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  237. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  238. package/pennyfarthing_scripts/migration/skill.py +0 -1
  239. package/pennyfarthing_scripts/migration/step.py +0 -1
  240. package/pennyfarthing_scripts/migration/validate.py +8 -5
  241. package/pennyfarthing_scripts/patch_mode.py +2 -2
  242. package/pennyfarthing_scripts/preflight/__init__.py +1 -1
  243. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  244. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  245. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  247. package/pennyfarthing_scripts/preflight/finish.py +0 -1
  248. package/pennyfarthing_scripts/pretooluse_hook.py +6 -7
  249. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  255. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  256. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  257. package/pennyfarthing_scripts/prime/cli.py +5 -1
  258. package/pennyfarthing_scripts/prime/loader.py +2 -3
  259. package/pennyfarthing_scripts/prime/persona.py +2 -1
  260. package/pennyfarthing_scripts/prime/tiers.py +4 -4
  261. package/pennyfarthing_scripts/schema_validation_hook.py +2 -3
  262. package/pennyfarthing_scripts/sprint/__init__.py +10 -12
  263. package/pennyfarthing_scripts/sprint/__main__.py +2 -2
  264. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  265. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  266. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  267. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  268. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  269. package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  270. package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  271. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  272. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  273. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  274. package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  276. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  277. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  278. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  279. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  280. package/pennyfarthing_scripts/sprint/archive.py +0 -1
  281. package/pennyfarthing_scripts/sprint/archive_epic.py +1 -4
  282. package/pennyfarthing_scripts/sprint/cli.py +34 -28
  283. package/pennyfarthing_scripts/sprint/epic_add.py +8 -1
  284. package/pennyfarthing_scripts/sprint/import_epic.py +42 -18
  285. package/pennyfarthing_scripts/sprint/loader.py +6 -0
  286. package/pennyfarthing_scripts/sprint/status.py +1 -2
  287. package/pennyfarthing_scripts/sprint/story_add.py +2 -2
  288. package/pennyfarthing_scripts/sprint/story_finish.py +3 -5
  289. package/pennyfarthing_scripts/sprint/story_update.py +11 -3
  290. package/pennyfarthing_scripts/sprint/validate_cmd.py +0 -1
  291. package/pennyfarthing_scripts/sprint/validator.py +120 -6
  292. package/pennyfarthing_scripts/sprint/work.py +1 -4
  293. package/pennyfarthing_scripts/sprint/yaml_io.py +10 -2
  294. package/pennyfarthing_scripts/story/__init__.py +14 -16
  295. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  296. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  297. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  298. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  299. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/story/size.py +0 -1
  302. package/pennyfarthing_scripts/story/template.py +0 -1
  303. package/pennyfarthing_scripts/swebench.py +1 -2
  304. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  305. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  306. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  307. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  308. package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  309. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  310. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  311. package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  312. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  313. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  314. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  315. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  316. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  317. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  318. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  319. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  320. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  321. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  322. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  323. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  324. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  325. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  326. package/pennyfarthing_scripts/tests/conftest.py +1 -2
  327. package/pennyfarthing_scripts/tests/test_brownfield.py +10 -13
  328. package/pennyfarthing_scripts/tests/test_cli_modules.py +0 -4
  329. package/pennyfarthing_scripts/tests/test_codemarkers.py +13 -8
  330. package/pennyfarthing_scripts/tests/test_common.py +9 -4
  331. package/pennyfarthing_scripts/tests/test_epic_shard_validation.py +699 -0
  332. package/pennyfarthing_scripts/tests/test_git_utils.py +10 -13
  333. package/pennyfarthing_scripts/tests/test_healthscore.py +17 -25
  334. package/pennyfarthing_scripts/tests/test_jira_package.py +0 -3
  335. package/pennyfarthing_scripts/tests/test_package_structure.py +3 -16
  336. package/pennyfarthing_scripts/tests/test_patch_mode.py +7 -11
  337. package/pennyfarthing_scripts/tests/test_prime.py +39 -21
  338. package/pennyfarthing_scripts/tests/test_sprint_package.py +3 -8
  339. package/pennyfarthing_scripts/tests/test_sprint_validator.py +53 -5
  340. package/pennyfarthing_scripts/tests/test_story_add.py +3 -7
  341. package/pennyfarthing_scripts/tests/test_story_package.py +0 -3
  342. package/pennyfarthing_scripts/tests/test_story_update.py +5 -10
  343. package/pennyfarthing_scripts/tests/test_tiers.py +18 -17
  344. package/pennyfarthing_scripts/tests/test_token_counting.py +19 -13
  345. package/pennyfarthing_scripts/tests/test_validate_cmd.py +2 -7
  346. package/pennyfarthing_scripts/tests/test_workflow_check.py +0 -2
  347. package/pennyfarthing_scripts/tests/test_yaml_io.py +0 -3
  348. package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  349. package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
  350. package/pennyfarthing_scripts/theme/cli.py +3 -2
  351. package/pennyfarthing_scripts/validate/__init__.py +21 -0
  352. package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  353. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  354. package/pennyfarthing_scripts/validate/adapters/__init__.py +0 -0
  355. package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  356. package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  357. package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  358. package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  359. package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  360. package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  361. package/pennyfarthing_scripts/validate/adapters/agent.py +239 -0
  362. package/pennyfarthing_scripts/validate/adapters/schema.py +30 -0
  363. package/pennyfarthing_scripts/validate/adapters/skill_command.py +292 -0
  364. package/pennyfarthing_scripts/validate/adapters/sprint.py +69 -0
  365. package/pennyfarthing_scripts/validate/adapters/workflow.py +320 -0
  366. package/pennyfarthing_scripts/validate/cli.py +141 -0
  367. package/pennyfarthing_scripts/welcome_hook.py +2 -3
  368. package/pennyfarthing_scripts/workflow.py +3 -3
  369. package/scripts/README.md +3 -15
  370. package/pennyfarthing-dist/commands/benchmark-control.md +0 -69
  371. package/pennyfarthing-dist/commands/benchmark.md +0 -485
  372. package/pennyfarthing-dist/commands/job-fair.md +0 -102
  373. package/pennyfarthing-dist/commands/solo.md +0 -447
  374. package/pennyfarthing-dist/guides/benchmarks.md +0 -62
  375. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  376. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +0 -59
  377. package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +0 -220
  378. package/pennyfarthing-dist/scripts/test/swebench-judge.py +0 -374
  379. package/pennyfarthing-dist/scripts/test/test-cache.sh +0 -165
  380. package/pennyfarthing-dist/scripts/test/test-setup.sh +0 -337
  381. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +0 -13
  382. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +0 -402
  383. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +0 -97
  384. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +0 -261
  385. package/pennyfarthing-dist/skills/judge/SKILL.md +0 -644
  386. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +0 -187
  387. package/pennyfarthing-dist/workflows/dev-story/checklist.md +0 -80
  388. package/pennyfarthing-dist/workflows/dev-story/instructions.xml +0 -410
  389. package/pennyfarthing-dist/workflows/dev-story/workflow.yaml +0 -50
  390. package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +0 -201
  391. package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +0 -156
  392. package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +0 -140
  393. package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +0 -203
  394. package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +0 -74
  395. package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +0 -27
  396. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  397. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  398. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  399. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  400. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  401. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  402. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  403. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  404. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  405. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  406. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  407. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -14,12 +14,10 @@ Acceptance Criteria:
14
14
  """
15
15
 
16
16
  from pathlib import Path
17
- from typing import Any
18
17
  from unittest.mock import patch
19
18
 
20
19
  import pytest
21
20
  from click.testing import CliRunner
22
- from ruamel.yaml.comments import CommentedMap
23
21
 
24
22
  from pennyfarthing_scripts.sprint.story_update import (
25
23
  update_story,
@@ -28,7 +26,6 @@ from pennyfarthing_scripts.sprint.yaml_io import (
28
26
  read_sprint,
29
27
  )
30
28
 
31
-
32
29
  # =============================================================================
33
30
  # Test Fixtures
34
31
  # =============================================================================
@@ -275,8 +272,6 @@ class TestUpdateStoryFields:
275
272
 
276
273
  def test_no_updates_provided(self, sprint_file: Path) -> None:
277
274
  """Calling with no field updates should succeed as a noop."""
278
- original_content = sprint_file.read_text()
279
-
280
275
  result = update_story(
281
276
  sprint_path=sprint_file,
282
277
  story_id="76-3",
@@ -378,8 +373,8 @@ class TestFindStoryAcrossEpics:
378
373
  class TestAutoCleanup:
379
374
  """Auto-cleanup rules for status transitions."""
380
375
 
381
- def test_done_removes_assigned_to(self, assigned_story_file: Path) -> None:
382
- """Setting status=done should remove assigned_to."""
376
+ def test_done_preserves_assigned_to(self, assigned_story_file: Path) -> None:
377
+ """Setting status=done should preserve assigned_to (no auto-removal)."""
383
378
  result = update_story(
384
379
  sprint_path=assigned_story_file,
385
380
  story_id="76-1",
@@ -390,7 +385,7 @@ class TestAutoCleanup:
390
385
 
391
386
  data = read_sprint(assigned_story_file)
392
387
  story = data["epics"][0]["stories"][0]
393
- assert "assigned_to" not in story
388
+ assert story["assigned_to"] == "kavery"
394
389
 
395
390
  def test_done_auto_sets_completed(self, assigned_story_file: Path) -> None:
396
391
  """Setting status=done should auto-set completed to today."""
@@ -611,10 +606,10 @@ class TestCLIIntegration:
611
606
 
612
607
  def test_update_command_exists(self) -> None:
613
608
  """story_update_command should be importable and be a Click command."""
614
- from pennyfarthing_scripts.sprint.story_update import story_update_command
615
-
616
609
  import click
617
610
 
611
+ from pennyfarthing_scripts.sprint.story_update import story_update_command
612
+
618
613
  assert isinstance(story_update_command, click.BaseCommand)
619
614
 
620
615
  def test_basic_update_via_cli(self, runner: CliRunner, sprint_file: Path) -> None:
@@ -12,11 +12,11 @@ Acceptance Criteria:
12
12
  - AC6: Token reduction verified: REFRESH ~600, HANDOFF ~700, MINIMAL ~200
13
13
  """
14
14
 
15
- import pytest
16
15
  from pathlib import Path
17
- from unittest.mock import patch, MagicMock
18
- import yaml
16
+ from unittest.mock import patch
19
17
 
18
+ import pytest
19
+ import yaml
20
20
 
21
21
  # =============================================================================
22
22
  # AC1: --tier CLI Argument Tests
@@ -314,10 +314,9 @@ class TestCompressedPersonaFormat:
314
314
 
315
315
  def test_compressed_persona_has_xml_structure(self, tmp_path: Path) -> None:
316
316
  """Test compressed persona uses XML format."""
317
- from pennyfarthing_scripts.prime.persona import format_persona_compressed
318
-
319
317
  # Import will fail until function is implemented
320
318
  from pennyfarthing_scripts.prime.models import Persona
319
+ from pennyfarthing_scripts.prime.persona import format_persona_compressed
321
320
 
322
321
  persona = Persona(
323
322
  character="Rosie the Riveter",
@@ -334,8 +333,8 @@ class TestCompressedPersonaFormat:
334
333
 
335
334
  def test_compressed_persona_includes_voice(self, tmp_path: Path) -> None:
336
335
  """Test compressed persona includes voice element."""
337
- from pennyfarthing_scripts.prime.persona import format_persona_compressed
338
336
  from pennyfarthing_scripts.prime.models import Persona
337
+ from pennyfarthing_scripts.prime.persona import format_persona_compressed
339
338
 
340
339
  persona = Persona(
341
340
  character="Rosie the Riveter",
@@ -350,8 +349,8 @@ class TestCompressedPersonaFormat:
350
349
 
351
350
  def test_compressed_persona_includes_style(self, tmp_path: Path) -> None:
352
351
  """Test compressed persona includes style element."""
353
- from pennyfarthing_scripts.prime.persona import format_persona_compressed
354
352
  from pennyfarthing_scripts.prime.models import Persona
353
+ from pennyfarthing_scripts.prime.persona import format_persona_compressed
355
354
 
356
355
  persona = Persona(
357
356
  character="Rosie the Riveter",
@@ -365,8 +364,8 @@ class TestCompressedPersonaFormat:
365
364
 
366
365
  def test_compressed_persona_includes_catchphrase_if_present(self, tmp_path: Path) -> None:
367
366
  """Test compressed persona includes catchphrase from quote."""
368
- from pennyfarthing_scripts.prime.persona import format_persona_compressed
369
367
  from pennyfarthing_scripts.prime.models import Persona
368
+ from pennyfarthing_scripts.prime.persona import format_persona_compressed
370
369
 
371
370
  persona = Persona(
372
371
  character="Rosie the Riveter",
@@ -382,8 +381,8 @@ class TestCompressedPersonaFormat:
382
381
 
383
382
  def test_compressed_persona_token_count(self, tmp_path: Path) -> None:
384
383
  """Test compressed persona is approximately 100 tokens (~400 chars)."""
385
- from pennyfarthing_scripts.prime.persona import format_persona_compressed
386
384
  from pennyfarthing_scripts.prime.models import Persona
385
+ from pennyfarthing_scripts.prime.persona import format_persona_compressed
387
386
 
388
387
  persona = Persona(
389
388
  character="Rosie the Riveter",
@@ -402,8 +401,8 @@ class TestCompressedPersonaFormat:
402
401
 
403
402
  def test_full_persona_token_count(self, tmp_path: Path) -> None:
404
403
  """Test full persona is approximately 300 tokens (~1200 chars)."""
404
+ from pennyfarthing_scripts.prime.models import CrewMember, Persona
405
405
  from pennyfarthing_scripts.prime.persona import format_persona_output
406
- from pennyfarthing_scripts.prime.models import Persona, CrewMember
407
406
 
408
407
  persona = Persona(
409
408
  character="Rosie the Riveter",
@@ -509,9 +508,10 @@ class TestDefaultBehavior:
509
508
 
510
509
  def test_existing_flags_still_work_with_tier(self, tmp_path: Path, capsys) -> None:
511
510
  """Test existing flags (--quiet, --json, etc.) work with --tier."""
512
- from pennyfarthing_scripts.prime.cli import prime
513
511
  import json
514
512
 
513
+ from pennyfarthing_scripts.prime.cli import prime
514
+
515
515
  # Setup
516
516
  pf_dir = tmp_path / ".pennyfarthing"
517
517
  pf_dir.mkdir()
@@ -548,7 +548,7 @@ class TestTierLoadingPaths:
548
548
 
549
549
  def test_full_tier_with_all_options(self, tmp_path: Path) -> None:
550
550
  """Test FULL tier with all context sources available."""
551
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
551
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
552
552
 
553
553
  # Setup complete project
554
554
  self._setup_complete_project(tmp_path)
@@ -569,7 +569,7 @@ class TestTierLoadingPaths:
569
569
 
570
570
  def test_full_tier_with_missing_optional(self, tmp_path: Path) -> None:
571
571
  """Test FULL tier gracefully handles missing optional components."""
572
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
572
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
573
573
 
574
574
  # Minimal setup - only agent definition
575
575
  pf_dir = tmp_path / ".pennyfarthing"
@@ -590,7 +590,7 @@ class TestTierLoadingPaths:
590
590
 
591
591
  def test_refresh_tier_components(self, tmp_path: Path) -> None:
592
592
  """Test REFRESH tier returns correct component set."""
593
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
593
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
594
594
 
595
595
  self._setup_complete_project(tmp_path)
596
596
 
@@ -612,7 +612,7 @@ class TestTierLoadingPaths:
612
612
 
613
613
  def test_handoff_tier_components(self, tmp_path: Path) -> None:
614
614
  """Test HANDOFF tier returns correct component set."""
615
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
615
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
616
616
 
617
617
  self._setup_complete_project(tmp_path)
618
618
 
@@ -633,7 +633,7 @@ class TestTierLoadingPaths:
633
633
 
634
634
  def test_minimal_tier_components(self, tmp_path: Path) -> None:
635
635
  """Test MINIMAL tier returns minimal component set."""
636
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
636
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
637
637
 
638
638
  self._setup_complete_project(tmp_path)
639
639
 
@@ -990,9 +990,10 @@ class TestTierIntegration:
990
990
 
991
991
  def test_json_output_includes_tier(self, tmp_path: Path, capsys) -> None:
992
992
  """Test JSON output includes current tier."""
993
- from pennyfarthing_scripts.prime.cli import prime
994
993
  import json
995
994
 
995
+ from pennyfarthing_scripts.prime.cli import prime
996
+
996
997
  pf_dir = tmp_path / ".pennyfarthing"
997
998
  pf_dir.mkdir()
998
999
  agents_dir = pf_dir / "agents"
@@ -15,12 +15,11 @@ Acceptance Criteria:
15
15
  This file tests the Python side (AC1, AC2, AC4).
16
16
  """
17
17
 
18
- import pytest
18
+ import json
19
19
  from pathlib import Path
20
20
  from unittest.mock import patch
21
- import yaml
22
- import json
23
21
 
22
+ import yaml
24
23
 
25
24
  # =============================================================================
26
25
  # AC1: Each component has an approximate token count
@@ -32,7 +31,7 @@ class TestComponentTokenCounting:
32
31
 
33
32
  def test_load_tier_components_returns_token_counts(self, tmp_path: Path) -> None:
34
33
  """Test load_tier_components returns token counts for each component."""
35
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
34
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
36
35
 
37
36
  self._setup_complete_project(tmp_path)
38
37
 
@@ -48,7 +47,7 @@ class TestComponentTokenCounting:
48
47
 
49
48
  def test_token_counts_include_all_full_tier_components(self, tmp_path: Path) -> None:
50
49
  """Test FULL tier returns token counts for all components."""
51
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
50
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
52
51
 
53
52
  self._setup_complete_project(tmp_path)
54
53
 
@@ -78,7 +77,7 @@ class TestComponentTokenCounting:
78
77
 
79
78
  def test_token_counts_are_positive_for_loaded_components(self, tmp_path: Path) -> None:
80
79
  """Test that loaded components have positive token counts."""
81
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
80
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
82
81
 
83
82
  self._setup_complete_project(tmp_path)
84
83
 
@@ -97,7 +96,7 @@ class TestComponentTokenCounting:
97
96
 
98
97
  def test_token_counts_zero_for_missing_components(self, tmp_path: Path) -> None:
99
98
  """Test that missing optional components have zero token counts."""
100
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
99
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
101
100
 
102
101
  # Minimal setup - only agent definition
103
102
  pf_dir = tmp_path / ".pennyfarthing"
@@ -120,7 +119,7 @@ class TestComponentTokenCounting:
120
119
 
121
120
  def test_refresh_tier_only_counts_included_components(self, tmp_path: Path) -> None:
122
121
  """Test REFRESH tier only includes counts for its components."""
123
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
122
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
124
123
 
125
124
  self._setup_complete_project(tmp_path)
126
125
 
@@ -145,7 +144,7 @@ class TestComponentTokenCounting:
145
144
 
146
145
  def test_handoff_tier_only_counts_included_components(self, tmp_path: Path) -> None:
147
146
  """Test HANDOFF tier only includes counts for its components."""
148
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
147
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
149
148
 
150
149
  self._setup_complete_project(tmp_path)
151
150
 
@@ -164,7 +163,7 @@ class TestComponentTokenCounting:
164
163
 
165
164
  def test_minimal_tier_only_counts_workflow_state(self, tmp_path: Path) -> None:
166
165
  """Test MINIMAL tier only counts workflow state."""
167
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
166
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
168
167
 
169
168
  self._setup_complete_project(tmp_path)
170
169
 
@@ -187,7 +186,7 @@ class TestComponentTokenCounting:
187
186
 
188
187
  def test_total_tokens_is_sum_of_components(self, tmp_path: Path) -> None:
189
188
  """Test that total_tokens equals sum of component counts."""
190
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier
189
+ from pennyfarthing_scripts.prime.tiers import ContextTier, load_tier_components
191
190
 
192
191
  self._setup_complete_project(tmp_path)
193
192
 
@@ -464,7 +463,11 @@ def hello():
464
463
 
465
464
  def test_component_token_count_within_10_percent_of_actual(self, tmp_path: Path) -> None:
466
465
  """Test component token counts are within 10% of actual tiktoken count."""
467
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier, estimate_tokens
466
+ from pennyfarthing_scripts.prime.tiers import (
467
+ ContextTier,
468
+ estimate_tokens,
469
+ load_tier_components,
470
+ )
468
471
 
469
472
  # Create a known-content project
470
473
  pf_dir = tmp_path / ".pennyfarthing"
@@ -495,7 +498,10 @@ def hello():
495
498
 
496
499
  def test_total_tokens_within_10_percent_of_sum(self, tmp_path: Path) -> None:
497
500
  """Test total_tokens is within 10% of manually summed content."""
498
- from pennyfarthing_scripts.prime.tiers import load_tier_components, ContextTier, estimate_tokens
501
+ from pennyfarthing_scripts.prime.tiers import (
502
+ ContextTier,
503
+ load_tier_components,
504
+ )
499
505
 
500
506
  pf_dir = tmp_path / ".pennyfarthing"
501
507
  pf_dir.mkdir()
@@ -13,21 +13,16 @@ Acceptance Criteria:
13
13
  """
14
14
 
15
15
  from pathlib import Path
16
- from typing import Any
17
- from unittest.mock import patch
18
16
 
19
17
  import pytest
20
18
  from click.testing import CliRunner
21
19
 
22
20
  from pennyfarthing_scripts.sprint.validate_cmd import (
23
- FormatIssue,
24
- ValidateResult,
25
21
  check_format_drift,
26
22
  validate_command,
27
23
  validate_sprint_yaml,
28
24
  )
29
25
 
30
-
31
26
  # =============================================================================
32
27
  # Test Fixtures
33
28
  # =============================================================================
@@ -382,7 +377,7 @@ class TestFixFlag:
382
377
  assert len(issues_before) > 0
383
378
 
384
379
  # Run validate with --fix
385
- result = validate_sprint_yaml(scrambled_keys_file, fix=True)
380
+ validate_sprint_yaml(scrambled_keys_file, fix=True)
386
381
 
387
382
  # After fix, re-check should show no drift
388
383
  issues_after = check_format_drift(scrambled_keys_file)
@@ -390,7 +385,7 @@ class TestFixFlag:
390
385
 
391
386
  def test_fix_converts_to_block_scalars(self, wrong_string_style_file: Path) -> None:
392
387
  """--fix should convert multiline strings to block scalar style."""
393
- result = validate_sprint_yaml(wrong_string_style_file, fix=True)
388
+ validate_sprint_yaml(wrong_string_style_file, fix=True)
394
389
 
395
390
  # Read back and check for block scalar
396
391
  content = wrong_string_style_file.read_text()
@@ -16,11 +16,9 @@ import json
16
16
  import subprocess
17
17
  import sys
18
18
  from pathlib import Path
19
- from typing import Any
20
19
  from unittest.mock import patch
21
20
 
22
21
  import pytest
23
-
24
22
  from click.testing import CliRunner
25
23
 
26
24
  from pennyfarthing_scripts.cli import cli
@@ -11,10 +11,8 @@ Acceptance Criteria:
11
11
  4. Key ordering matches sprint-template.yaml
12
12
  """
13
13
 
14
- import os
15
14
  from pathlib import Path
16
15
  from typing import Any
17
- from unittest.mock import patch
18
16
 
19
17
  import pytest
20
18
 
@@ -27,7 +25,6 @@ from pennyfarthing_scripts.sprint.yaml_io import (
27
25
  write_sprint,
28
26
  )
29
27
 
30
-
31
28
  # =============================================================================
32
29
  # Test Fixtures
33
30
  # =============================================================================
@@ -225,9 +225,10 @@ def create(name: str, base: str | None, user: bool):
225
225
  Arguments:
226
226
  NAME - Name for the new theme (lowercase, hyphens allowed)
227
227
  """
228
- import yaml
229
228
  from pathlib import Path
230
229
 
230
+ import yaml
231
+
231
232
  from pennyfarthing_scripts.common.config import get_project_root
232
233
  from pennyfarthing_scripts.common.themes import (
233
234
  get_current_theme,
@@ -282,5 +283,5 @@ def create(name: str, base: str | None, user: bool):
282
283
  click.echo(f" File: {target_path}")
283
284
  click.echo()
284
285
  click.echo("Next steps:")
285
- click.echo(f" 1. Edit the theme file to customize your agents")
286
+ click.echo(" 1. Edit the theme file to customize your agents")
286
287
  click.echo(f" 2. Run 'pf theme set {name}' to activate")
@@ -0,0 +1,21 @@
1
+ """Top-level validate command — auto-discovers and runs project validators."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+
8
+ @dataclass
9
+ class ValidateReport:
10
+ """Unified report from a single validator domain."""
11
+
12
+ validator: str
13
+ passed: int = 0
14
+ warnings: int = 0
15
+ errors: int = 0
16
+ details: list[str] = field(default_factory=list)
17
+ fixed: bool = False
18
+
19
+ @property
20
+ def success(self) -> bool:
21
+ return self.errors == 0