@pennyfarthing/core 10.0.5 → 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 (580) hide show
  1. package/README.md +19 -22
  2. package/package.json +17 -11
  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 +346 -13
  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/init.d.ts +7 -0
  17. package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
  18. package/packages/core/dist/cli/commands/init.js +41 -8
  19. package/packages/core/dist/cli/commands/init.js.map +1 -1
  20. package/packages/core/dist/cli/commands/uninstall.d.ts.map +1 -1
  21. package/packages/core/dist/cli/commands/uninstall.js +24 -13
  22. package/packages/core/dist/cli/commands/uninstall.js.map +1 -1
  23. package/packages/core/dist/cli/commands/update-consolidation.test.js +0 -10
  24. package/packages/core/dist/cli/commands/update-consolidation.test.js.map +1 -1
  25. package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
  26. package/packages/core/dist/cli/commands/update.js +26 -0
  27. package/packages/core/dist/cli/commands/update.js.map +1 -1
  28. package/packages/core/dist/cli/index.js +1 -1
  29. package/packages/core/dist/cli/index.js.map +1 -1
  30. package/packages/core/dist/cli/ocean-profiles.test.js.map +1 -1
  31. package/packages/core/dist/cli/theme-maker.test.js +64 -115
  32. package/packages/core/dist/cli/theme-maker.test.js.map +1 -1
  33. package/packages/core/dist/cli/utils/python.d.ts +22 -0
  34. package/packages/core/dist/cli/utils/python.d.ts.map +1 -0
  35. package/packages/core/dist/cli/utils/python.js +102 -0
  36. package/packages/core/dist/cli/utils/python.js.map +1 -0
  37. package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
  38. package/packages/core/dist/cli/utils/settings.js +10 -0
  39. package/packages/core/dist/cli/utils/settings.js.map +1 -1
  40. package/packages/core/dist/index.d.ts +1 -1
  41. package/packages/core/dist/index.d.ts.map +1 -1
  42. package/packages/core/dist/index.js +2 -2
  43. package/packages/core/dist/index.js.map +1 -1
  44. package/packages/core/dist/plugins/plugin-discovery.d.ts +116 -0
  45. package/packages/core/dist/plugins/plugin-discovery.d.ts.map +1 -0
  46. package/packages/core/dist/plugins/plugin-discovery.js +165 -0
  47. package/packages/core/dist/plugins/plugin-discovery.js.map +1 -0
  48. package/packages/core/dist/plugins/plugin-discovery.test.d.ts +22 -0
  49. package/packages/core/dist/plugins/plugin-discovery.test.d.ts.map +1 -0
  50. package/packages/core/dist/plugins/plugin-discovery.test.js +498 -0
  51. package/packages/core/dist/plugins/plugin-discovery.test.js.map +1 -0
  52. package/packages/core/dist/scripts/generate-spider-report.js.map +1 -1
  53. package/packages/core/dist/workflow/context-watch.d.ts +80 -0
  54. package/packages/core/dist/workflow/context-watch.d.ts.map +1 -0
  55. package/packages/core/dist/workflow/context-watch.js +235 -0
  56. package/packages/core/dist/workflow/context-watch.js.map +1 -0
  57. package/packages/core/dist/workflow/context-watch.test.d.ts +1 -0
  58. package/packages/core/dist/workflow/context-watch.test.d.ts.map +1 -0
  59. package/packages/core/dist/workflow/context-watch.test.js +746 -0
  60. package/packages/core/dist/workflow/context-watch.test.js.map +1 -0
  61. package/packages/core/dist/workflow/file-watch.d.ts +82 -0
  62. package/packages/core/dist/workflow/file-watch.d.ts.map +1 -0
  63. package/packages/core/dist/workflow/file-watch.js +198 -0
  64. package/packages/core/dist/workflow/file-watch.js.map +1 -0
  65. package/packages/core/dist/workflow/file-watch.test.d.ts +21 -0
  66. package/packages/core/dist/workflow/file-watch.test.d.ts.map +1 -0
  67. package/packages/core/dist/workflow/file-watch.test.js +469 -0
  68. package/packages/core/dist/workflow/file-watch.test.js.map +1 -0
  69. package/packages/core/dist/workflow/observation-writer.d.ts +79 -0
  70. package/packages/core/dist/workflow/observation-writer.d.ts.map +1 -0
  71. package/packages/core/dist/workflow/observation-writer.js +97 -0
  72. package/packages/core/dist/workflow/observation-writer.js.map +1 -0
  73. package/packages/core/dist/workflow/observation-writer.test.d.ts +18 -0
  74. package/packages/core/dist/workflow/observation-writer.test.d.ts.map +1 -0
  75. package/packages/core/dist/workflow/observation-writer.test.js +424 -0
  76. package/packages/core/dist/workflow/observation-writer.test.js.map +1 -0
  77. package/packages/core/dist/workflow/story-workflow-routing.test.js +4 -2
  78. package/packages/core/dist/workflow/story-workflow-routing.test.js.map +1 -1
  79. package/packages/core/dist/workflow/tandem-lifecycle.d.ts +117 -0
  80. package/packages/core/dist/workflow/tandem-lifecycle.d.ts.map +1 -0
  81. package/packages/core/dist/workflow/tandem-lifecycle.js +186 -0
  82. package/packages/core/dist/workflow/tandem-lifecycle.js.map +1 -0
  83. package/packages/core/dist/workflow/tandem-lifecycle.test.d.ts +16 -0
  84. package/packages/core/dist/workflow/tandem-lifecycle.test.d.ts.map +1 -0
  85. package/packages/core/dist/workflow/tandem-lifecycle.test.js +531 -0
  86. package/packages/core/dist/workflow/tandem-lifecycle.test.js.map +1 -0
  87. package/packages/core/dist/workflow/tool-watch.d.ts +68 -0
  88. package/packages/core/dist/workflow/tool-watch.d.ts.map +1 -0
  89. package/packages/core/dist/workflow/tool-watch.js +166 -0
  90. package/packages/core/dist/workflow/tool-watch.js.map +1 -0
  91. package/packages/core/dist/workflow/tool-watch.test.d.ts +18 -0
  92. package/packages/core/dist/workflow/tool-watch.test.d.ts.map +1 -0
  93. package/packages/core/dist/workflow/tool-watch.test.js +718 -0
  94. package/packages/core/dist/workflow/tool-watch.test.js.map +1 -0
  95. package/packages/core/dist/workflow/workflow-migration.test.js +8 -4
  96. package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -1
  97. package/packages/core/dist/workflow/workflow-schema.d.ts +7 -0
  98. package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
  99. package/packages/core/dist/workflow/workflow-schema.js +44 -0
  100. package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
  101. package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -1
  102. package/packages/core/dist/workflow/workflow-schema.test.js +192 -0
  103. package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -1
  104. package/pennyfarthing-dist/agents/README.md +1 -3
  105. package/pennyfarthing-dist/agents/architect.md +0 -6
  106. package/pennyfarthing-dist/agents/devops.md +0 -6
  107. package/pennyfarthing-dist/agents/handoff.md +18 -3
  108. package/pennyfarthing-dist/agents/orchestrator.md +0 -6
  109. package/pennyfarthing-dist/agents/pm.md +0 -6
  110. package/pennyfarthing-dist/agents/sm-finish.md +1 -1
  111. package/pennyfarthing-dist/agents/sm-handoff.md +27 -4
  112. package/pennyfarthing-dist/agents/sm.md +11 -11
  113. package/pennyfarthing-dist/agents/tandem-backseat.md +119 -0
  114. package/pennyfarthing-dist/commands/architect.md +11 -3
  115. package/pennyfarthing-dist/commands/close-epic.md +24 -131
  116. package/pennyfarthing-dist/commands/create-theme.md +14 -24
  117. package/pennyfarthing-dist/commands/dev.md +11 -3
  118. package/pennyfarthing-dist/commands/devops.md +11 -3
  119. package/pennyfarthing-dist/commands/health-check.md +1 -3
  120. package/pennyfarthing-dist/commands/help.md +8 -12
  121. package/pennyfarthing-dist/commands/list-themes.md +14 -16
  122. package/pennyfarthing-dist/commands/orchestrator.md +11 -3
  123. package/pennyfarthing-dist/commands/parallel-work.md +1 -3
  124. package/pennyfarthing-dist/commands/pm.md +11 -3
  125. package/pennyfarthing-dist/commands/prime.md +6 -6
  126. package/pennyfarthing-dist/commands/reviewer.md +11 -3
  127. package/pennyfarthing-dist/commands/run-ci.md +1 -1
  128. package/pennyfarthing-dist/commands/set-theme.md +14 -51
  129. package/pennyfarthing-dist/commands/setup.md +5 -1
  130. package/pennyfarthing-dist/commands/show-theme.md +14 -16
  131. package/pennyfarthing-dist/commands/sm.md +11 -3
  132. package/pennyfarthing-dist/commands/tea.md +11 -3
  133. package/pennyfarthing-dist/commands/tech-writer.md +11 -3
  134. package/pennyfarthing-dist/commands/theme-maker.md +14 -671
  135. package/pennyfarthing-dist/commands/theme.md +95 -0
  136. package/pennyfarthing-dist/commands/ux-designer.md +11 -3
  137. package/pennyfarthing-dist/commands/work.md +3 -5
  138. package/pennyfarthing-dist/guides/agent-behavior.md +62 -6
  139. package/pennyfarthing-dist/guides/agent-coordination.md +11 -13
  140. package/pennyfarthing-dist/guides/agent-template-tactical.md +2 -3
  141. package/pennyfarthing-dist/guides/bikelane.md +3 -2
  142. package/pennyfarthing-dist/guides/command-tag-taxonomy.md +212 -0
  143. package/pennyfarthing-dist/guides/hooks.md +5 -5
  144. package/pennyfarthing-dist/guides/patterns/fan-out-fan-in-pattern.md +3 -3
  145. package/pennyfarthing-dist/guides/patterns/helper-delegation-pattern.md +9 -59
  146. package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +4 -5
  147. package/pennyfarthing-dist/guides/prime.md +2 -2
  148. package/pennyfarthing-dist/guides/scale-levels.md +4 -6
  149. package/pennyfarthing-dist/guides/skill-schema.md +4 -4
  150. package/pennyfarthing-dist/guides/tandem-protocol.md +158 -0
  151. package/pennyfarthing-dist/personas/themes/discworld.yaml +1 -1
  152. package/pennyfarthing-dist/personas/themes/fifth-element.yaml +295 -0
  153. package/pennyfarthing-dist/scripts/README.md +1 -1
  154. package/pennyfarthing-dist/scripts/core/agent-session.sh +6 -2
  155. package/pennyfarthing-dist/scripts/core/check-context.sh +0 -0
  156. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +0 -0
  157. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  158. package/pennyfarthing-dist/scripts/core/prime.sh +8 -10
  159. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  160. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +0 -0
  161. package/pennyfarthing-dist/scripts/git/git-status-all.sh +0 -0
  162. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +8 -6
  163. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  164. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +0 -0
  165. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  166. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +131 -54
  167. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  168. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  169. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  170. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +0 -0
  171. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +32 -15
  172. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +4 -3
  173. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  174. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +11 -5
  175. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  176. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  177. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  178. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  179. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  180. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  181. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +0 -0
  182. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +0 -0
  183. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +0 -0
  184. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  185. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +0 -0
  186. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  187. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  188. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  189. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  190. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  191. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  192. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  193. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  194. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  195. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  196. package/pennyfarthing-dist/scripts/misc/README.md +1 -1
  197. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  198. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  199. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  200. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  201. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  202. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  203. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  204. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  205. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
  206. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  207. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  208. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  209. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  210. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  211. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  212. package/pennyfarthing-dist/scripts/misc/statusline.sh +50 -8
  213. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  214. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +1 -2
  215. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  216. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  217. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  218. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  219. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  220. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  221. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  222. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +5 -5
  223. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  224. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  225. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  226. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  227. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  228. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +3 -79
  229. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  230. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  231. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  232. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  233. package/pennyfarthing-dist/scripts/theme/README.md +1 -1
  234. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  235. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -1
  236. package/pennyfarthing-dist/scripts/workflow/README.md +2 -2
  237. package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
  238. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  239. package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
  240. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +10 -144
  241. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +0 -0
  242. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  243. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +0 -0
  244. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +0 -0
  245. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +0 -0
  246. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +0 -0
  247. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +0 -0
  248. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +0 -0
  249. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +0 -0
  250. package/pennyfarthing-dist/skills/dev-patterns/SKILL.md +2 -2
  251. package/pennyfarthing-dist/skills/skill-registry.schema.json +8 -0
  252. package/pennyfarthing-dist/skills/skill-registry.yaml +21 -17
  253. package/pennyfarthing-dist/skills/sprint/skill.md +25 -2
  254. package/pennyfarthing-dist/skills/story/scripts/create-story.sh +0 -0
  255. package/pennyfarthing-dist/skills/story/scripts/size-story.sh +0 -0
  256. package/pennyfarthing-dist/skills/story/scripts/story-template.sh +0 -0
  257. package/pennyfarthing-dist/skills/theme/skill.md +290 -75
  258. package/pennyfarthing-dist/skills/theme-creation/SKILL.md +23 -166
  259. package/pennyfarthing-dist/skills/workflow/scripts/list-workflows.sh +0 -0
  260. package/pennyfarthing-dist/skills/workflow/scripts/resume-workflow.sh +0 -0
  261. package/pennyfarthing-dist/skills/workflow/scripts/show-workflow.sh +0 -0
  262. package/pennyfarthing-dist/skills/workflow/scripts/start-workflow.sh +0 -0
  263. package/pennyfarthing-dist/skills/workflow/scripts/workflow-status.sh +0 -0
  264. package/pennyfarthing-dist/skills/workflow/skill.md +27 -4
  265. package/pennyfarthing-dist/templates/agent-scopes.yaml.template +0 -11
  266. package/pennyfarthing-dist/templates/auto-load-sm.sh.template +14 -0
  267. package/pennyfarthing-dist/templates/settings.local.json.template +9 -0
  268. package/pennyfarthing-dist/workflows/2party-tdd.yaml +399 -0
  269. package/pennyfarthing-dist/workflows/architecture/workflow.yaml +65 -0
  270. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +70 -0
  271. package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +41 -24
  272. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +61 -0
  273. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  274. package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  276. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  277. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  278. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  279. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  280. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  281. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  282. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  283. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  284. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  285. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  286. package/pennyfarthing_scripts/bellmode_hook.py +202 -47
  287. package/pennyfarthing_scripts/brownfield/__init__.py +6 -6
  288. package/pennyfarthing_scripts/brownfield/__main__.py +1 -0
  289. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  290. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  291. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  292. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  293. package/pennyfarthing_scripts/brownfield/cli.py +0 -1
  294. package/pennyfarthing_scripts/brownfield/discover.py +1 -2
  295. package/pennyfarthing_scripts/cli.py +23 -3
  296. package/pennyfarthing_scripts/codemarkers/__init__.py +23 -0
  297. package/pennyfarthing_scripts/codemarkers/__main__.py +6 -0
  298. package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
  299. package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
  302. package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
  303. package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
  304. package/pennyfarthing_scripts/codemarkers/analyze.py +501 -0
  305. package/pennyfarthing_scripts/codemarkers/cli.py +179 -0
  306. package/pennyfarthing_scripts/codemarkers/formatters.py +88 -0
  307. package/pennyfarthing_scripts/codemarkers/models.py +60 -0
  308. package/pennyfarthing_scripts/common/__init__.py +8 -9
  309. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  310. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  311. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  312. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  313. package/pennyfarthing_scripts/common/config.py +1 -1
  314. package/pennyfarthing_scripts/complexity/__init__.py +15 -0
  315. package/pennyfarthing_scripts/complexity/__main__.py +6 -0
  316. package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
  317. package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
  318. package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
  319. package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
  320. package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
  321. package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
  322. package/pennyfarthing_scripts/complexity/analyze.py +207 -0
  323. package/pennyfarthing_scripts/complexity/cli.py +82 -0
  324. package/pennyfarthing_scripts/complexity/formatters.py +64 -0
  325. package/pennyfarthing_scripts/complexity/models.py +32 -0
  326. package/pennyfarthing_scripts/context.py +14 -15
  327. package/pennyfarthing_scripts/deadcode/__init__.py +6 -0
  328. package/pennyfarthing_scripts/deadcode/__main__.py +6 -0
  329. package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
  330. package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
  331. package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
  332. package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
  333. package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
  334. package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
  335. package/pennyfarthing_scripts/deadcode/analyze.py +322 -0
  336. package/pennyfarthing_scripts/deadcode/cli.py +163 -0
  337. package/pennyfarthing_scripts/deadcode/formatters.py +106 -0
  338. package/pennyfarthing_scripts/deadcode/models.py +54 -0
  339. package/pennyfarthing_scripts/dependencies/__init__.py +20 -0
  340. package/pennyfarthing_scripts/dependencies/__main__.py +5 -0
  341. package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
  342. package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
  343. package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
  344. package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
  345. package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
  346. package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
  347. package/pennyfarthing_scripts/dependencies/analyze.py +155 -0
  348. package/pennyfarthing_scripts/dependencies/cli.py +76 -0
  349. package/pennyfarthing_scripts/dependencies/formatters.py +63 -0
  350. package/pennyfarthing_scripts/dependencies/models.py +39 -0
  351. package/pennyfarthing_scripts/git/__init__.py +5 -5
  352. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  353. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  354. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  355. package/pennyfarthing_scripts/git/create_branches.py +3 -2
  356. package/pennyfarthing_scripts/git/status_all.py +1 -1
  357. package/pennyfarthing_scripts/healthscore/__init__.py +21 -0
  358. package/pennyfarthing_scripts/healthscore/__main__.py +14 -0
  359. package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
  360. package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
  361. package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
  362. package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
  363. package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
  364. package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
  365. package/pennyfarthing_scripts/healthscore/analyze.py +591 -0
  366. package/pennyfarthing_scripts/healthscore/cli.py +80 -0
  367. package/pennyfarthing_scripts/healthscore/formatters.py +46 -0
  368. package/pennyfarthing_scripts/healthscore/models.py +43 -0
  369. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +0 -0
  370. package/pennyfarthing_scripts/hooks.py +8 -11
  371. package/pennyfarthing_scripts/hotspots/__init__.py +6 -6
  372. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  373. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  374. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  375. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  376. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  377. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  378. package/pennyfarthing_scripts/hotspots/analyze.py +155 -14
  379. package/pennyfarthing_scripts/hotspots/cli.py +12 -10
  380. package/pennyfarthing_scripts/hotspots/models.py +0 -1
  381. package/pennyfarthing_scripts/jira/__init__.py +15 -17
  382. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  383. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  384. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  385. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  386. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  387. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  388. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  389. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  390. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  391. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  392. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  393. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  394. package/pennyfarthing_scripts/jira/bidirectional.py +44 -18
  395. package/pennyfarthing_scripts/jira/claim.py +21 -0
  396. package/pennyfarthing_scripts/jira/cli.py +6 -3
  397. package/pennyfarthing_scripts/jira/client.py +32 -4
  398. package/pennyfarthing_scripts/jira/create.py +45 -1
  399. package/pennyfarthing_scripts/jira/epic.py +3 -2
  400. package/pennyfarthing_scripts/jira/reconcile.py +0 -1
  401. package/pennyfarthing_scripts/jira/story.py +2 -0
  402. package/pennyfarthing_scripts/jira/sync.py +1 -1
  403. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  404. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  405. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  406. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  407. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  408. package/pennyfarthing_scripts/migration/skill.py +0 -1
  409. package/pennyfarthing_scripts/migration/step.py +0 -1
  410. package/pennyfarthing_scripts/migration/validate.py +8 -5
  411. package/pennyfarthing_scripts/patch_mode.py +2 -2
  412. package/pennyfarthing_scripts/preflight/__init__.py +1 -1
  413. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  414. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  415. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  416. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  417. package/pennyfarthing_scripts/preflight/finish.py +0 -1
  418. package/pennyfarthing_scripts/pretooluse_hook.py +6 -7
  419. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  420. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  421. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  422. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  423. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  424. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  425. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  426. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  427. package/pennyfarthing_scripts/prime/cli.py +5 -1
  428. package/pennyfarthing_scripts/prime/loader.py +2 -3
  429. package/pennyfarthing_scripts/prime/persona.py +2 -1
  430. package/pennyfarthing_scripts/prime/tiers.py +4 -4
  431. package/pennyfarthing_scripts/schema_validation_hook.py +2 -3
  432. package/pennyfarthing_scripts/sprint/__init__.py +10 -12
  433. package/pennyfarthing_scripts/sprint/__main__.py +2 -2
  434. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  435. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  436. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  437. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  438. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  439. package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
  440. package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
  441. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  442. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  443. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  444. package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
  445. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  446. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  447. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  448. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  449. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  450. package/pennyfarthing_scripts/sprint/archive.py +0 -1
  451. package/pennyfarthing_scripts/sprint/archive_epic.py +198 -97
  452. package/pennyfarthing_scripts/sprint/cli.py +62 -46
  453. package/pennyfarthing_scripts/sprint/epic_add.py +8 -1
  454. package/pennyfarthing_scripts/sprint/import_epic.py +42 -18
  455. package/pennyfarthing_scripts/sprint/loader.py +6 -0
  456. package/pennyfarthing_scripts/sprint/status.py +1 -2
  457. package/pennyfarthing_scripts/sprint/story_add.py +202 -27
  458. package/pennyfarthing_scripts/sprint/story_finish.py +209 -0
  459. package/pennyfarthing_scripts/sprint/story_update.py +11 -3
  460. package/pennyfarthing_scripts/sprint/validate_cmd.py +0 -1
  461. package/pennyfarthing_scripts/sprint/validator.py +120 -6
  462. package/pennyfarthing_scripts/sprint/work.py +28 -7
  463. package/pennyfarthing_scripts/sprint/yaml_io.py +10 -2
  464. package/pennyfarthing_scripts/story/__init__.py +14 -16
  465. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  466. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  467. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  468. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  469. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  470. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  471. package/pennyfarthing_scripts/story/size.py +0 -1
  472. package/pennyfarthing_scripts/story/template.py +0 -1
  473. package/pennyfarthing_scripts/swebench.py +1 -2
  474. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  475. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  476. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  477. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  478. package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
  479. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  480. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  481. package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
  482. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  483. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  484. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  485. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  486. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  487. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  488. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  489. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  490. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  491. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  492. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  493. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  494. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  495. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  496. package/pennyfarthing_scripts/tests/conftest.py +1 -2
  497. package/pennyfarthing_scripts/tests/test_brownfield.py +10 -13
  498. package/pennyfarthing_scripts/tests/test_cli_modules.py +0 -4
  499. package/pennyfarthing_scripts/tests/test_codemarkers.py +687 -0
  500. package/pennyfarthing_scripts/tests/test_common.py +9 -4
  501. package/pennyfarthing_scripts/tests/test_epic_shard_validation.py +699 -0
  502. package/pennyfarthing_scripts/tests/test_git_utils.py +10 -13
  503. package/pennyfarthing_scripts/tests/test_healthscore.py +516 -0
  504. package/pennyfarthing_scripts/tests/test_jira_package.py +0 -3
  505. package/pennyfarthing_scripts/tests/test_package_structure.py +3 -16
  506. package/pennyfarthing_scripts/tests/test_patch_mode.py +7 -11
  507. package/pennyfarthing_scripts/tests/test_prime.py +39 -21
  508. package/pennyfarthing_scripts/tests/test_sprint_package.py +3 -8
  509. package/pennyfarthing_scripts/tests/test_sprint_validator.py +53 -5
  510. package/pennyfarthing_scripts/tests/test_story_add.py +3 -7
  511. package/pennyfarthing_scripts/tests/test_story_package.py +0 -3
  512. package/pennyfarthing_scripts/tests/test_story_update.py +5 -10
  513. package/pennyfarthing_scripts/tests/test_tiers.py +18 -17
  514. package/pennyfarthing_scripts/tests/test_token_counting.py +19 -13
  515. package/pennyfarthing_scripts/tests/test_validate_cmd.py +2 -7
  516. package/pennyfarthing_scripts/tests/test_workflow_check.py +0 -2
  517. package/pennyfarthing_scripts/tests/test_yaml_io.py +0 -3
  518. package/pennyfarthing_scripts/theme/__init__.py +5 -0
  519. package/pennyfarthing_scripts/theme/__main__.py +6 -0
  520. package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
  521. package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
  522. package/pennyfarthing_scripts/theme/cli.py +287 -0
  523. package/pennyfarthing_scripts/validate/__init__.py +21 -0
  524. package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
  525. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  526. package/pennyfarthing_scripts/validate/adapters/__init__.py +0 -0
  527. package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  528. package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
  529. package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
  530. package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
  531. package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
  532. package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
  533. package/pennyfarthing_scripts/validate/adapters/agent.py +239 -0
  534. package/pennyfarthing_scripts/validate/adapters/schema.py +30 -0
  535. package/pennyfarthing_scripts/validate/adapters/skill_command.py +292 -0
  536. package/pennyfarthing_scripts/validate/adapters/sprint.py +69 -0
  537. package/pennyfarthing_scripts/validate/adapters/workflow.py +320 -0
  538. package/pennyfarthing_scripts/validate/cli.py +141 -0
  539. package/pennyfarthing_scripts/welcome_hook.py +2 -3
  540. package/pennyfarthing_scripts/workflow.py +3 -3
  541. package/scripts/README.md +41 -0
  542. package/pennyfarthing-dist/agents/workflow-status-check.md +0 -96
  543. package/pennyfarthing-dist/commands/benchmark-control.md +0 -69
  544. package/pennyfarthing-dist/commands/benchmark.md +0 -485
  545. package/pennyfarthing-dist/commands/job-fair.md +0 -102
  546. package/pennyfarthing-dist/commands/solo.md +0 -447
  547. package/pennyfarthing-dist/guides/benchmarks.md +0 -62
  548. package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
  549. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +0 -59
  550. package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +0 -220
  551. package/pennyfarthing-dist/scripts/test/swebench-judge.py +0 -374
  552. package/pennyfarthing-dist/scripts/test/test-cache.sh +0 -165
  553. package/pennyfarthing-dist/scripts/test/test-setup.sh +0 -337
  554. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +0 -13
  555. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +0 -402
  556. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +0 -97
  557. package/pennyfarthing-dist/skills/finalize-run/SKILL.md +0 -261
  558. package/pennyfarthing-dist/skills/judge/SKILL.md +0 -644
  559. package/pennyfarthing-dist/skills/persona-benchmark/SKILL.md +0 -187
  560. package/pennyfarthing-dist/workflows/dev-story/checklist.md +0 -80
  561. package/pennyfarthing-dist/workflows/dev-story/instructions.xml +0 -410
  562. package/pennyfarthing-dist/workflows/dev-story/workflow.yaml +0 -50
  563. package/pennyfarthing-dist/workflows/quick-spec/steps/step-01-understand.md +0 -201
  564. package/pennyfarthing-dist/workflows/quick-spec/steps/step-02-investigate.md +0 -156
  565. package/pennyfarthing-dist/workflows/quick-spec/steps/step-03-generate.md +0 -140
  566. package/pennyfarthing-dist/workflows/quick-spec/steps/step-04-review.md +0 -203
  567. package/pennyfarthing-dist/workflows/quick-spec/tech-spec-template.md +0 -74
  568. package/pennyfarthing-dist/workflows/quick-spec/workflow.yaml +0 -27
  569. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  570. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  571. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  572. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  573. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  574. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  575. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  576. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  577. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  578. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  579. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  580. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -35,21 +35,21 @@ def estimate_tokens(text: str) -> int:
35
35
  return max(1, len(text) // 4)
36
36
 
37
37
 
38
- from pennyfarthing_scripts.prime.loader import (
38
+ from pennyfarthing_scripts.prime.loader import ( # noqa: E402
39
39
  load_agent_definition,
40
40
  load_behavior_guide,
41
41
  load_session_context,
42
42
  load_sidecars,
43
43
  load_sprint_context,
44
44
  )
45
- from pennyfarthing_scripts.prime.persona import (
45
+ from pennyfarthing_scripts.prime.persona import ( # noqa: E402
46
46
  format_persona_compressed,
47
47
  get_crew_manifest,
48
48
  get_user_title,
49
49
  is_character_voice_enabled,
50
50
  load_persona,
51
51
  )
52
- from pennyfarthing_scripts.prime.workflow import detect_workflow_state
52
+ from pennyfarthing_scripts.prime.workflow import detect_workflow_state # noqa: E402
53
53
 
54
54
 
55
55
  class ContextTier(Enum):
@@ -78,7 +78,7 @@ def tier_from_string(value: str) -> ContextTier:
78
78
  return ContextTier(normalized)
79
79
  except ValueError:
80
80
  valid = ", ".join(t.value for t in ContextTier)
81
- raise ValueError(f"Invalid tier '{value}'. Must be one of: {valid}")
81
+ raise ValueError(f"Invalid tier '{value}'. Must be one of: {valid}") from None
82
82
 
83
83
 
84
84
  def load_tier_components(
@@ -29,12 +29,11 @@ from pathlib import Path
29
29
  sys.path.insert(0, str(Path(__file__).parent))
30
30
 
31
31
  from hooks import (
32
- read_stdin_json,
33
- output_hook_response,
34
32
  HookResponse,
33
+ output_hook_response,
34
+ read_stdin_json,
35
35
  )
36
36
 
37
-
38
37
  # =============================================================================
39
38
  # File Type Detection
40
39
  # =============================================================================
@@ -18,6 +18,16 @@ Usage:
18
18
  """
19
19
 
20
20
  # Re-export from loader for backwards compatibility
21
+ # Import submodules to make them accessible
22
+ # CLI entry point - import module, not function, so "from sprint import cli" gets the module
23
+ from pennyfarthing_scripts.sprint import (
24
+ archive,
25
+ cli,
26
+ loader,
27
+ status,
28
+ work,
29
+ )
30
+ from pennyfarthing_scripts.sprint.cli import main
21
31
  from pennyfarthing_scripts.sprint.loader import (
22
32
  find_epic,
23
33
  find_story,
@@ -31,18 +41,6 @@ from pennyfarthing_scripts.sprint.loader import (
31
41
  load_sprint,
32
42
  )
33
43
 
34
- # Import submodules to make them accessible
35
- from pennyfarthing_scripts.sprint import (
36
- archive,
37
- loader,
38
- status,
39
- work,
40
- )
41
-
42
- # CLI entry point - import module, not function, so "from sprint import cli" gets the module
43
- from pennyfarthing_scripts.sprint import cli
44
- from pennyfarthing_scripts.sprint.cli import main
45
-
46
44
  __all__ = [
47
45
  # Loader functions
48
46
  "find_epic",
@@ -4,7 +4,7 @@ Entry point for python -m pennyfarthing_scripts.sprint
4
4
 
5
5
  import sys
6
6
 
7
- from pennyfarthing_scripts.sprint.cli import cli
7
+ from pennyfarthing_scripts.sprint.cli import sprint
8
8
 
9
9
  if __name__ == "__main__":
10
- sys.exit(cli())
10
+ sys.exit(sprint())
@@ -4,7 +4,6 @@ Sprint story archiving.
4
4
  Provides functions for archiving completed stories.
5
5
  """
6
6
 
7
- from pathlib import Path
8
7
  from typing import Any
9
8
 
10
9
  from pennyfarthing_scripts.common.config import get_project_root
@@ -1,24 +1,29 @@
1
1
  """
2
2
  Sprint epic archiving.
3
3
 
4
- Provides functions for archiving completed epics to sprint archive files.
5
- Handles archive file creation, epic completion detection, and YAML updates.
4
+ Archives completed epics by moving their shard files to sprint/archive/.
5
+ The sprint completed file references archived epics by ID (not inlined).
6
6
  """
7
7
 
8
+ import shutil
8
9
  from datetime import date
9
10
  from pathlib import Path
10
11
  from typing import Any
11
12
 
12
- from pennyfarthing_scripts.common.config import get_project_root, load_yaml_config
13
+ from pennyfarthing_scripts.common.config import get_project_root
13
14
  from pennyfarthing_scripts.sprint.loader import load_sprint
14
- from pennyfarthing_scripts.sprint.yaml_io import write_sprint
15
+ from pennyfarthing_scripts.sprint.yaml_io import (
16
+ _get_epic_ref,
17
+ _make_yaml,
18
+ _read_yaml_file,
19
+ _write_yaml_file,
20
+ read_sprint,
21
+ )
15
22
 
16
23
 
17
24
  def get_archive_path(project_root: Path | None = None) -> Path:
18
25
  """Get the archive file path for the current sprint.
19
26
 
20
- Creates the archive file with a template if it doesn't exist.
21
-
22
27
  Args:
23
28
  project_root: Project root path (defaults to auto-detect)
24
29
 
@@ -33,9 +38,7 @@ def get_archive_path(project_root: Path | None = None) -> Path:
33
38
 
34
39
  sprint_info = sprint_data["sprint"]
35
40
 
36
- # Extract sprint identifier (YYWW format from jira_sprint_name)
37
41
  sprint_name = sprint_info.get("jira_sprint_name", "")
38
- # Extract "2604" from "TO Sprint 2604"
39
42
  sprint_id = sprint_name.split()[-1] if sprint_name else str(sprint_info.get("number", "unknown"))
40
43
 
41
44
  archive_path = root / "sprint" / "archive" / f"sprint-{sprint_id}-completed.yaml"
@@ -57,7 +60,6 @@ def ensure_archive_file(project_root: Path | None = None) -> Path:
57
60
  if archive_path.exists():
58
61
  return archive_path
59
62
 
60
- # Create archive file with template
61
63
  sprint_data = load_sprint(root)
62
64
  sprint_info = sprint_data.get("sprint", {})
63
65
 
@@ -65,7 +67,7 @@ def ensure_archive_file(project_root: Path | None = None) -> Path:
65
67
  sprint_id = sprint_info.get("jira_sprint_id", "")
66
68
  goal = sprint_info.get("goal", "")
67
69
 
68
- template = f"""# Sprint {sprint_name} - Completed Stories
70
+ template = f"""# Sprint {sprint_name} - Completed Work
69
71
  # Jira Sprint ID: {sprint_id}
70
72
  # Archived: {date.today().isoformat()}
71
73
 
@@ -75,7 +77,11 @@ sprint:
75
77
  jira_sprint_name: "{sprint_name}"
76
78
  goal: {goal}
77
79
 
78
- completed:
80
+ completed_epics:
81
+ # Epic shard files live in sprint/archive/epic-{{ref}}.yaml
82
+
83
+ completed_stories:
84
+ # Orphan stories not belonging to an epic
79
85
  """
80
86
 
81
87
  archive_path.parent.mkdir(parents=True, exist_ok=True)
@@ -84,25 +90,92 @@ completed:
84
90
  return archive_path
85
91
 
86
92
 
93
+ def _load_archive_file(archive_path: Path) -> dict[str, Any]:
94
+ """Load the sprint archive file, handling both old and new formats.
95
+
96
+ Args:
97
+ archive_path: Path to the archive YAML file
98
+
99
+ Returns:
100
+ Archive data dict with completed_epics and completed_stories
101
+ """
102
+ yml = _make_yaml()
103
+ with open(archive_path) as f:
104
+ data = yml.load(f)
105
+
106
+ if data is None:
107
+ data = {}
108
+
109
+ # Ensure new-format keys exist
110
+ if "completed_epics" not in data:
111
+ data["completed_epics"] = []
112
+ if "completed_stories" not in data:
113
+ data["completed_stories"] = []
114
+
115
+ # Normalize: ensure lists are not None
116
+ if data["completed_epics"] is None:
117
+ data["completed_epics"] = []
118
+ if data["completed_stories"] is None:
119
+ data["completed_stories"] = []
120
+
121
+ return data
122
+
123
+
124
+ def _write_archive_file(archive_path: Path, data: dict[str, Any]) -> None:
125
+ """Write the sprint archive file.
126
+
127
+ Args:
128
+ archive_path: Path to the archive YAML file
129
+ data: Archive data dict
130
+ """
131
+ import io
132
+
133
+ from ruamel.yaml.comments import CommentedMap, CommentedSeq
134
+
135
+ yml = _make_yaml()
136
+
137
+ # Build output preserving comments at the top
138
+ cm = CommentedMap()
139
+ if "sprint" in data:
140
+ cm["sprint"] = data["sprint"]
141
+
142
+ # completed_epics as string refs
143
+ epic_refs = CommentedSeq()
144
+ for ref in data.get("completed_epics", []):
145
+ epic_refs.append(ref)
146
+ cm["completed_epics"] = epic_refs
147
+
148
+ # completed_stories for orphans
149
+ stories = CommentedSeq()
150
+ for story in data.get("completed_stories", []):
151
+ stories.append(story)
152
+ cm["completed_stories"] = stories
153
+
154
+ stream = io.StringIO()
155
+ yml.dump(cm, stream)
156
+ output = stream.getvalue()
157
+
158
+ # Clean trailing whitespace
159
+ lines = output.split("\n")
160
+ cleaned = [line.rstrip() for line in lines]
161
+ result = "\n".join(cleaned).rstrip("\n") + "\n"
162
+
163
+ archive_path.write_text(result)
164
+
165
+
87
166
  def is_epic_complete(epic: dict[str, Any]) -> tuple[bool, list[str]]:
88
167
  """Check if an epic is complete by examining story statuses.
89
168
 
90
- An epic is complete if:
91
- - It has status 'done' or 'completed', OR
92
- - All of its stories have a terminal status ('done', 'completed', or 'cancelled')
93
-
94
169
  Args:
95
170
  epic: Epic dict from sprint YAML
96
171
 
97
172
  Returns:
98
173
  Tuple of (is_complete, list of incomplete story IDs)
99
174
  """
100
- # Check if epic itself is marked done
101
175
  epic_status = epic.get("status", "backlog")
102
176
  if epic_status in ("done", "completed"):
103
177
  return True, []
104
178
 
105
- # Check all stories
106
179
  stories = epic.get("stories", [])
107
180
  if not stories:
108
181
  return False, []
@@ -152,6 +225,10 @@ def archive_epic(
152
225
  ) -> dict[str, Any]:
153
226
  """Archive a completed epic.
154
227
 
228
+ Moves the epic shard file to sprint/archive/, adds the epic ref to the
229
+ sprint completed file, and removes it from the current sprint index.
230
+ Context files are also moved to archive.
231
+
155
232
  Args:
156
233
  epic_id: Epic ID to archive (e.g., "epic-64" or "MSSCI-12465")
157
234
  project_root: Project root path (defaults to auto-detect)
@@ -162,18 +239,23 @@ def archive_epic(
162
239
  Dict with success status and details
163
240
  """
164
241
  root = project_root or get_project_root()
165
- sprint_data = load_sprint(root)
242
+ sprint_dir = root / "sprint"
243
+ archive_dir = sprint_dir / "archive"
244
+ archive_dir.mkdir(parents=True, exist_ok=True)
245
+
246
+ sprint_path = sprint_dir / "current-sprint.yaml"
247
+ sprint_data = read_sprint(sprint_path)
166
248
 
167
249
  if not sprint_data or "epics" not in sprint_data:
168
250
  return {"success": False, "error": "Could not load sprint data"}
169
251
 
170
- # Find the epic
252
+ # Find the epic in merged data
171
253
  epic = None
172
- epic_index = None
173
- for i, e in enumerate(sprint_data["epics"]):
174
- if e.get("id") == epic_id or e.get("jira") == epic_id:
254
+ for e in sprint_data["epics"]:
255
+ eid = str(e.get("id", ""))
256
+ ejira = str(e.get("jira", ""))
257
+ if eid == epic_id or ejira == epic_id:
175
258
  epic = e
176
- epic_index = i
177
259
  break
178
260
 
179
261
  if not epic:
@@ -188,83 +270,104 @@ def archive_epic(
188
270
  "incomplete_stories": incomplete,
189
271
  }
190
272
 
273
+ # Determine the shard ref (filename stem)
274
+ epic_ref = _get_epic_ref(epic)
275
+ shard_file = sprint_dir / f"epic-{epic_ref}.yaml"
276
+ archive_shard = archive_dir / f"epic-{epic_ref}.yaml"
277
+ story_count = len(epic.get("stories", []))
278
+ total_points = sum(s.get("points", 0) for s in epic.get("stories", []))
279
+
191
280
  if dry_run:
281
+ msg_parts = [f"Would archive {epic_id} ({story_count} stories, {total_points} pts)"]
282
+ if shard_file.exists():
283
+ msg_parts.append(f" Move: {shard_file.name} → archive/")
284
+ # Check for context file
285
+ for ctx_name in [f"context-epic-{epic_ref}.md", f"context-epic-{epic.get('id', '')}.md"]:
286
+ ctx_file = sprint_dir / "context" / ctx_name
287
+ if ctx_file.exists():
288
+ msg_parts.append(f" Move: context/{ctx_name} → archive/")
289
+ break
192
290
  return {
193
291
  "success": True,
194
292
  "dry_run": True,
195
293
  "epic": epic,
196
- "message": f"Would archive {epic_id} ({len(epic.get('stories', []))} stories)",
294
+ "stories_archived": story_count,
295
+ "total_points": total_points,
296
+ "message": "\n".join(msg_parts),
197
297
  }
198
298
 
199
- # Ensure archive file exists
299
+ # 1. Update epic status in the shard before moving
300
+ if shard_file.exists():
301
+ shard_data = _read_yaml_file(shard_file)
302
+ shard_data["status"] = "done"
303
+ if "completed" not in shard_data:
304
+ shard_data["completed"] = date.today().isoformat()
305
+ _write_yaml_file(shard_file, shard_data)
306
+ # Move shard to archive
307
+ shutil.move(str(shard_file), str(archive_shard))
308
+ else:
309
+ # No shard file on disk — write epic data directly to archive
310
+ epic["status"] = "done"
311
+ if "completed" not in epic:
312
+ epic["completed"] = date.today().isoformat()
313
+ _write_yaml_file(archive_shard, epic)
314
+
315
+ # 2. Move context file if it exists
316
+ context_moved = None
317
+ for ctx_name in [f"context-epic-{epic_ref}.md", f"context-epic-{epic.get('id', '')}.md"]:
318
+ ctx_file = sprint_dir / "context" / ctx_name
319
+ if ctx_file.exists():
320
+ shutil.move(str(ctx_file), str(archive_dir / ctx_name))
321
+ context_moved = ctx_name
322
+ break
323
+
324
+ # 3. Add epic ref to sprint completed file
200
325
  archive_path = ensure_archive_file(root)
326
+ archive_data = _load_archive_file(archive_path)
327
+
328
+ # Add ref if not already present
329
+ if epic_ref not in archive_data["completed_epics"]:
330
+ archive_data["completed_epics"].append(epic_ref)
331
+ _write_archive_file(archive_path, archive_data)
332
+
333
+ # 4. Remove epic from current-sprint.yaml index
334
+ # Re-read the raw index (not merged) to update refs
335
+ yml = _make_yaml()
336
+ with open(sprint_path) as f:
337
+ index_data = yml.load(f)
338
+
339
+ epics_list = index_data.get("epics", [])
340
+ # Remove the matching ref (string) or dict
341
+ new_epics = []
342
+ for item in epics_list:
343
+ if isinstance(item, str):
344
+ if item != epic_ref:
345
+ new_epics.append(item)
346
+ else:
347
+ item_id = str(item.get("id", ""))
348
+ item_jira = str(item.get("jira", ""))
349
+ if item_id != epic_id and item_jira != epic_id:
350
+ new_epics.append(item)
201
351
 
202
- # Build archive entries for all stories
203
- archive_entries = []
204
- epic_jira = epic.get("jira", epic_id)
205
- for story in epic.get("stories", []):
206
- entry = {
207
- "id": story.get("id") or story.get("jira"),
208
- "epic": epic_jira,
209
- "title": story.get("title", ""),
210
- "points": story.get("points", 0),
211
- "completed": story.get("completed", date.today().isoformat()),
212
- }
213
- if story.get("pr"):
214
- entry["pr"] = story["pr"]
215
- archive_entries.append(entry)
216
-
217
- # Append to archive file
218
- with open(archive_path, "a") as f:
219
- # Add epic header comment
220
- epic_title = epic.get("title", epic_id)
221
- f.write(f"\n # {epic_id}: {epic_title} - COMPLETE\n")
222
-
223
- for entry in archive_entries:
224
- f.write(f" - id: {entry['id']}\n")
225
- f.write(f" epic: {entry['epic']}\n")
226
- # Escape quotes in title
227
- title = entry['title'].replace('"', '\\"')
228
- f.write(f' title: "{title}"\n')
229
- f.write(f" points: {entry['points']}\n")
230
- f.write(f" completed: {entry['completed']}\n")
231
- if entry.get("pr"):
232
- f.write(f" pr: {entry['pr']}\n")
233
-
234
- # Remove epic from current-sprint.yaml
235
- sprint_path = root / "sprint" / "current-sprint.yaml"
236
- del sprint_data["epics"][epic_index]
237
-
238
- # Note: We do NOT update completed_points here because stories were already
239
- # marked done - their points are already counted. Archiving just moves them
240
- # to the archive file without changing the accounting.
241
-
242
- # Write updated sprint file (shard-aware)
243
- write_sprint(sprint_path, sprint_data)
244
-
245
- # Clean up shard file if it exists
246
- epic_jira_key = epic.get("jira", "")
247
- epic_id_val = str(epic.get("id", ""))
248
- sprint_dir = root / "sprint"
249
- for ref in [epic_jira_key, epic_id_val]:
250
- if ref:
251
- shard_file = sprint_dir / f"epic-{ref}.yaml"
252
- if shard_file.exists():
253
- shard_file.unlink()
254
- break
352
+ from ruamel.yaml.comments import CommentedSeq
353
+ index_data["epics"] = CommentedSeq(new_epics)
354
+ _write_yaml_file(sprint_path, index_data)
255
355
 
256
356
  result = {
257
357
  "success": True,
258
358
  "epic_id": epic_id,
259
- "jira": epic_jira,
260
- "stories_archived": len(archive_entries),
261
- "archive_path": str(archive_path),
262
- "message": f"Archived {epic_id} with {len(archive_entries)} stories",
359
+ "epic_ref": epic_ref,
360
+ "stories_archived": story_count,
361
+ "total_points": total_points,
362
+ "archive_shard": str(archive_shard),
363
+ "context_moved": context_moved,
364
+ "message": f"Archived {epic_id} ({story_count} stories, {total_points} pts) → archive/epic-{epic_ref}.yaml",
263
365
  }
264
366
 
265
367
  # Update Jira if requested
368
+ epic_jira = epic.get("jira", "")
266
369
  if update_jira and epic_jira:
267
- result["jira_updated"] = _update_jira_epic(epic_jira)
370
+ result["jira_updated"] = _update_jira_epic(str(epic_jira))
268
371
 
269
372
  return result
270
373
 
@@ -321,7 +424,7 @@ def archive_all_completed(
321
424
  results = []
322
425
  for item in completed:
323
426
  epic = item["epic"]
324
- epic_id = epic.get("id")
427
+ epic_id = str(epic.get("id", ""))
325
428
  result = archive_epic(
326
429
  epic_id,
327
430
  project_root=root,
@@ -330,22 +433,18 @@ def archive_all_completed(
330
433
  )
331
434
  results.append(result)
332
435
 
436
+ total_stories = sum(r.get("stories_archived", 0) for r in results if r.get("success"))
437
+ total_points = sum(r.get("total_points", 0) for r in results if r.get("success"))
438
+
333
439
  return {
334
440
  "success": all(r.get("success") for r in results),
335
441
  "archived": results,
336
- "message": f"Processed {len(results)} epics",
442
+ "message": f"Archived {len(results)} epics ({total_stories} stories, {total_points} pts)",
337
443
  }
338
444
 
339
445
 
340
446
  def main(args: list[str] | None = None) -> int:
341
- """CLI entry point for epic archiving.
342
-
343
- Args:
344
- args: Command line arguments
345
-
346
- Returns:
347
- Exit code
348
- """
447
+ """CLI entry point for epic archiving."""
349
448
  import argparse
350
449
  import sys
351
450
 
@@ -387,14 +486,16 @@ def main(args: list[str] | None = None) -> int:
387
486
  print("[DRY-RUN]", result.get("message"))
388
487
  if "archived" in result:
389
488
  for r in result["archived"]:
390
- epic_id = r.get("epic", {}).get("id") if "epic" in r else r.get("epic_id")
391
- stories = len(r.get("epic", {}).get("stories", [])) if "epic" in r else r.get("stories_archived", 0)
392
- print(f" Would archive: {epic_id} ({stories} stories)")
489
+ print(f" {r.get('message')}")
393
490
  else:
394
491
  print(result.get("message"))
395
492
  if "archived" in result:
396
493
  for r in result["archived"]:
397
- print(f" {r.get('epic_id')}: {r.get('stories_archived')} stories")
494
+ print(f" \u2713 {r.get('message')}")
495
+ elif result.get("archive_shard"):
496
+ print(f" Shard: {result.get('archive_shard')}")
497
+ if result.get("context_moved"):
498
+ print(f" Context: {result.get('context_moved')}")
398
499
  return 0
399
500
  else:
400
501
  print(f"Failed: {result.get('error')}", file=sys.stderr)