@pennyfarthing/core 10.0.2 → 10.0.3

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 (792) hide show
  1. package/README.md +287 -0
  2. package/package.json +30 -44
  3. package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts +13 -0
  4. package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts.map +1 -0
  5. package/packages/core/dist/cli/commands/doctor-file-layout.test.js +234 -0
  6. package/packages/core/dist/cli/commands/doctor-file-layout.test.js.map +1 -0
  7. package/{dist → packages/core/dist}/cli/commands/doctor.d.ts +8 -0
  8. package/{dist → packages/core/dist}/cli/commands/doctor.d.ts.map +1 -1
  9. package/{dist → packages/core/dist}/cli/commands/doctor.js +224 -3
  10. package/packages/core/dist/cli/commands/doctor.js.map +1 -0
  11. package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.js +1 -1
  12. package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.js.map +1 -1
  13. package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.js +1 -1
  14. package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.js.map +1 -1
  15. package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts +19 -0
  16. package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts.map +1 -0
  17. package/packages/core/dist/cli/commands/hooks-consolidation.test.js +358 -0
  18. package/packages/core/dist/cli/commands/hooks-consolidation.test.js.map +1 -0
  19. package/{dist → packages/core/dist}/cli/commands/update.d.ts.map +1 -1
  20. package/{dist → packages/core/dist}/cli/commands/update.js +53 -1
  21. package/{dist → packages/core/dist}/cli/commands/update.js.map +1 -1
  22. package/{dist → packages/core/dist}/cli/utils/settings.d.ts.map +1 -1
  23. package/{dist → packages/core/dist}/cli/utils/settings.js +24 -0
  24. package/packages/core/dist/cli/utils/settings.js.map +1 -0
  25. package/{dist → packages/core/dist}/cli/utils/themes.d.ts +1 -0
  26. package/packages/core/dist/cli/utils/themes.d.ts.map +1 -0
  27. package/{dist → packages/core/dist}/cli/utils/themes.js.map +1 -1
  28. package/pennyfarthing-dist/agents/sm-setup.md +4 -4
  29. package/pennyfarthing-dist/agents/sm.md +8 -1
  30. package/pennyfarthing-dist/guides/bell-mode.md +65 -0
  31. package/pennyfarthing-dist/guides/benchmarks.md +62 -0
  32. package/pennyfarthing-dist/guides/bikelane.md +86 -0
  33. package/pennyfarthing-dist/guides/prime.md +72 -0
  34. package/pennyfarthing-dist/guides/reflector.md +59 -0
  35. package/pennyfarthing-dist/guides/relay-mode.md +53 -0
  36. package/pennyfarthing-dist/guides/tirepump.md +54 -0
  37. package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +59 -58
  38. package/pennyfarthing-dist/personas/themes/blade-runner.yaml +10 -10
  39. package/pennyfarthing-dist/personas/themes/doctor-who.yaml +10 -10
  40. package/pennyfarthing-dist/personas/themes/dune.yaml +64 -69
  41. package/pennyfarthing-dist/personas/themes/firefly.yaml +60 -73
  42. package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +60 -69
  43. package/pennyfarthing-dist/personas/themes/harry-potter.yaml +59 -73
  44. package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +45 -57
  45. package/pennyfarthing-dist/personas/themes/mad-max.yaml +5 -11
  46. package/pennyfarthing-dist/personas/themes/princess-bride.yaml +53 -63
  47. package/pennyfarthing-dist/personas/themes/sandman.yaml +59 -59
  48. package/pennyfarthing-dist/personas/themes/the-matrix.yaml +61 -62
  49. package/pennyfarthing-dist/personas/themes/west-wing.yaml +8 -9
  50. package/pennyfarthing-dist/scripts/core/agent-session.sh +0 -0
  51. package/pennyfarthing-dist/scripts/core/check-context.sh +0 -0
  52. package/pennyfarthing-dist/scripts/core/handoff-marker.sh +0 -0
  53. package/pennyfarthing-dist/scripts/core/phase-check-start.sh +0 -0
  54. package/pennyfarthing-dist/scripts/core/prime.sh +0 -0
  55. package/pennyfarthing-dist/scripts/cyclist/is-cyclist.sh +0 -0
  56. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +0 -0
  57. package/pennyfarthing-dist/scripts/git/git-status-all.sh +0 -0
  58. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +0 -0
  59. package/pennyfarthing-dist/scripts/git/release.sh +0 -0
  60. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +0 -0
  61. package/pennyfarthing-dist/scripts/health/drift-detection.sh +0 -0
  62. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +0 -0
  63. package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +0 -0
  64. package/pennyfarthing-dist/scripts/hooks/context-warning.sh +0 -0
  65. package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +32 -0
  66. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +0 -0
  67. package/pennyfarthing-dist/scripts/hooks/post-merge.sh +0 -0
  68. package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +0 -0
  69. package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +0 -0
  70. package/pennyfarthing-dist/scripts/hooks/pre-push.sh +0 -0
  71. package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +0 -0
  72. package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +0 -0
  73. package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +0 -0
  74. package/pennyfarthing-dist/scripts/hooks/session-start.sh +0 -0
  75. package/pennyfarthing-dist/scripts/hooks/session-stop.sh +0 -0
  76. package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +0 -0
  77. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +0 -0
  78. package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +12 -91
  79. package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +11 -86
  80. package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +0 -0
  81. package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +11 -255
  82. package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +0 -0
  83. package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +0 -0
  84. package/pennyfarthing-dist/scripts/lib/background-tasks.sh +0 -0
  85. package/pennyfarthing-dist/scripts/lib/checkpoint.sh +0 -0
  86. package/pennyfarthing-dist/scripts/lib/common.sh +0 -0
  87. package/pennyfarthing-dist/scripts/lib/file-lock.sh +0 -0
  88. package/pennyfarthing-dist/scripts/lib/logging.sh +0 -0
  89. package/pennyfarthing-dist/scripts/lib/retry.sh +0 -0
  90. package/pennyfarthing-dist/scripts/maintenance/migrate-theme-schema.mjs +0 -0
  91. package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +0 -0
  92. package/pennyfarthing-dist/scripts/misc/add-short-names.sh +0 -0
  93. package/pennyfarthing-dist/scripts/misc/add_short_names.py +0 -0
  94. package/pennyfarthing-dist/scripts/misc/backlog.sh +0 -0
  95. package/pennyfarthing-dist/scripts/misc/check-status.sh +0 -0
  96. package/pennyfarthing-dist/scripts/misc/find-related-work.sh +0 -0
  97. package/pennyfarthing-dist/scripts/misc/generate-skill-docs.sh +0 -0
  98. package/pennyfarthing-dist/scripts/misc/log-skill-usage.sh +0 -0
  99. package/pennyfarthing-dist/scripts/misc/migrate-bmad-workflow.sh +0 -0
  100. package/pennyfarthing-dist/scripts/misc/migrate_bmad_workflow.py +0 -0
  101. package/pennyfarthing-dist/scripts/misc/repo-scan.sh +0 -0
  102. package/pennyfarthing-dist/scripts/misc/repo-utils.sh +0 -0
  103. package/pennyfarthing-dist/scripts/misc/run-ci.sh +0 -0
  104. package/pennyfarthing-dist/scripts/misc/run-timestamp.sh +0 -0
  105. package/pennyfarthing-dist/scripts/misc/session-cleanup.sh +0 -0
  106. package/pennyfarthing-dist/scripts/misc/skill-usage-report.sh +0 -0
  107. package/pennyfarthing-dist/scripts/misc/statusline.sh +0 -0
  108. package/pennyfarthing-dist/scripts/misc/uninstall.sh +0 -0
  109. package/pennyfarthing-dist/scripts/misc/validate-subagent-frontmatter.sh +0 -0
  110. package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +0 -0
  111. package/pennyfarthing-dist/scripts/sprint/archive-story.sh +0 -0
  112. package/pennyfarthing-dist/scripts/sprint/available-stories.sh +0 -0
  113. package/pennyfarthing-dist/scripts/sprint/check-story.sh +0 -0
  114. package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +0 -0
  115. package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +0 -0
  116. package/pennyfarthing-dist/scripts/sprint/list-future.sh +0 -0
  117. package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +0 -0
  118. package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +0 -0
  119. package/pennyfarthing-dist/scripts/sprint/sprint-common.sh +0 -0
  120. package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +0 -0
  121. package/pennyfarthing-dist/scripts/sprint/sprint-metrics.sh +0 -0
  122. package/pennyfarthing-dist/scripts/sprint/sprint-status.sh +0 -0
  123. package/pennyfarthing-dist/scripts/sprint/validate-sprint-yaml.sh +0 -0
  124. package/pennyfarthing-dist/scripts/story/create-story.sh +0 -0
  125. package/pennyfarthing-dist/scripts/story/size-story.sh +0 -0
  126. package/pennyfarthing-dist/scripts/story/story-template.sh +0 -0
  127. package/pennyfarthing-dist/scripts/test/ensure-swebench-data.sh +0 -0
  128. package/pennyfarthing-dist/scripts/test/swebench-judge.py +0 -0
  129. package/pennyfarthing-dist/scripts/test/test-cache.sh +0 -0
  130. package/pennyfarthing-dist/scripts/test/test-setup.sh +0 -0
  131. package/pennyfarthing-dist/scripts/tests/check.test.sh +0 -0
  132. package/pennyfarthing-dist/scripts/tests/dev-story-workflow-import.test.sh +0 -0
  133. package/pennyfarthing-dist/scripts/tests/epics-and-stories-workflow-import.test.sh +0 -0
  134. package/pennyfarthing-dist/scripts/tests/handoff-phase-update.test.sh +0 -0
  135. package/pennyfarthing-dist/scripts/tests/implementation-readiness-workflow-import.test.sh +0 -0
  136. package/pennyfarthing-dist/scripts/tests/migrate-bmad-workflow.test.sh +0 -0
  137. package/pennyfarthing-dist/scripts/tests/prd-workflow-import.test.sh +0 -0
  138. package/pennyfarthing-dist/scripts/tests/project-context-workflow-import.test.sh +0 -0
  139. package/pennyfarthing-dist/scripts/tests/test-character-voice.sh +0 -0
  140. package/pennyfarthing-dist/scripts/tests/test-drift-detection.sh +0 -0
  141. package/pennyfarthing-dist/scripts/tests/test-post-merge-hook.sh +0 -0
  142. package/pennyfarthing-dist/scripts/tests/test-session-checkpoint.sh +0 -0
  143. package/pennyfarthing-dist/scripts/tests/test-solo-command.sh +0 -0
  144. package/pennyfarthing-dist/scripts/tests/ux-design-workflow-import.test.sh +0 -0
  145. package/pennyfarthing-dist/scripts/theme/compute-theme-tiers.sh +0 -0
  146. package/pennyfarthing-dist/scripts/theme/compute_theme_tiers.py +0 -0
  147. package/pennyfarthing-dist/scripts/theme/list-themes.sh +0 -0
  148. package/pennyfarthing-dist/scripts/theme/update-theme-tiers.sh +0 -0
  149. package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +0 -0
  150. package/pennyfarthing-dist/scripts/workflow/check.py +0 -0
  151. package/pennyfarthing-dist/scripts/workflow/check.sh +0 -0
  152. package/pennyfarthing-dist/scripts/workflow/complete-step.py +0 -0
  153. package/pennyfarthing-dist/scripts/workflow/finish-story.sh +0 -0
  154. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +0 -0
  155. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.py +0 -0
  156. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +0 -0
  157. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +0 -0
  158. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +0 -0
  159. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +0 -0
  160. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +0 -0
  161. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +0 -0
  162. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +0 -0
  163. package/pennyfarthing-dist/skills/jira/SKILL.md +107 -408
  164. package/pennyfarthing-dist/skills/sprint/scripts/archive-story.sh +0 -0
  165. package/pennyfarthing-dist/skills/sprint/scripts/available-stories.sh +0 -0
  166. package/pennyfarthing-dist/skills/sprint/scripts/check-story.sh +0 -0
  167. package/pennyfarthing-dist/skills/sprint/scripts/create-jira-epic.sh +17 -95
  168. package/pennyfarthing-dist/skills/sprint/scripts/new-sprint.sh +0 -0
  169. package/pennyfarthing-dist/skills/sprint/scripts/promote-epic.sh +0 -0
  170. package/pennyfarthing-dist/skills/sprint/scripts/sprint-info.sh +0 -0
  171. package/pennyfarthing-dist/skills/sprint/scripts/sprint-status.sh +0 -0
  172. package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +20 -90
  173. package/pennyfarthing-dist/skills/story/scripts/create-story.sh +0 -0
  174. package/pennyfarthing-dist/skills/story/scripts/size-story.sh +0 -0
  175. package/pennyfarthing-dist/skills/story/scripts/story-template.sh +0 -0
  176. package/pennyfarthing-dist/skills/workflow/scripts/list-workflows.sh +0 -0
  177. package/pennyfarthing-dist/skills/workflow/scripts/resume-workflow.sh +0 -0
  178. package/pennyfarthing-dist/skills/workflow/scripts/show-workflow.sh +0 -0
  179. package/pennyfarthing-dist/skills/workflow/scripts/start-workflow.sh +0 -0
  180. package/pennyfarthing-dist/skills/workflow/scripts/workflow-status.sh +0 -0
  181. package/pennyfarthing-dist/templates/settings.local.json.template +9 -1
  182. package/pennyfarthing_scripts/README.md +66 -0
  183. package/pennyfarthing_scripts/__init__.py +17 -0
  184. package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  185. package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  186. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  187. package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
  188. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  189. package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
  190. package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
  191. package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
  192. package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
  193. package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
  194. package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
  195. package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
  196. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  197. package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
  198. package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
  199. package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
  200. package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
  201. package/pennyfarthing_scripts/bellmode_hook.py +154 -0
  202. package/pennyfarthing_scripts/brownfield/__init__.py +35 -0
  203. package/pennyfarthing_scripts/brownfield/__main__.py +7 -0
  204. package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
  205. package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
  206. package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
  207. package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
  208. package/pennyfarthing_scripts/brownfield/cli.py +131 -0
  209. package/pennyfarthing_scripts/brownfield/discover.py +753 -0
  210. package/pennyfarthing_scripts/cli.py +184 -0
  211. package/pennyfarthing_scripts/common/__init__.py +49 -0
  212. package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
  213. package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
  214. package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
  215. package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
  216. package/pennyfarthing_scripts/common/config.py +91 -0
  217. package/pennyfarthing_scripts/common/output.py +180 -0
  218. package/pennyfarthing_scripts/common/themes.py +253 -0
  219. package/pennyfarthing_scripts/config.py +21 -0
  220. package/pennyfarthing_scripts/context.py +414 -0
  221. package/pennyfarthing_scripts/git/__init__.py +29 -0
  222. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  223. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  224. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  225. package/pennyfarthing_scripts/git/create_branches.py +439 -0
  226. package/pennyfarthing_scripts/git/status_all.py +310 -0
  227. package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +7 -0
  228. package/pennyfarthing_scripts/hooks.py +454 -0
  229. package/pennyfarthing_scripts/hotspots/__init__.py +31 -0
  230. package/pennyfarthing_scripts/hotspots/__main__.py +6 -0
  231. package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
  232. package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
  233. package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
  234. package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
  235. package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
  236. package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
  237. package/pennyfarthing_scripts/hotspots/analyze.py +472 -0
  238. package/pennyfarthing_scripts/hotspots/cli.py +152 -0
  239. package/pennyfarthing_scripts/hotspots/formatters.py +109 -0
  240. package/pennyfarthing_scripts/hotspots/models.py +60 -0
  241. package/pennyfarthing_scripts/jira/__init__.py +99 -0
  242. package/pennyfarthing_scripts/jira/__main__.py +10 -0
  243. package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
  244. package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
  245. package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
  246. package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
  247. package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
  248. package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
  249. package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
  250. package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
  251. package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
  252. package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
  253. package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
  254. package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
  255. package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
  256. package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
  257. package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
  258. package/pennyfarthing_scripts/jira/bidirectional.py +561 -0
  259. package/pennyfarthing_scripts/jira/claim.py +211 -0
  260. package/pennyfarthing_scripts/jira/cli.py +277 -0
  261. package/pennyfarthing_scripts/jira/client.py +762 -0
  262. package/pennyfarthing_scripts/jira/create.py +267 -0
  263. package/pennyfarthing_scripts/jira/epic.py +176 -0
  264. package/pennyfarthing_scripts/jira/operations.py +124 -0
  265. package/pennyfarthing_scripts/jira/reconcile.py +277 -0
  266. package/pennyfarthing_scripts/jira/story.py +219 -0
  267. package/pennyfarthing_scripts/jira/sync.py +350 -0
  268. package/pennyfarthing_scripts/jira_bidirectional_sync.py +37 -0
  269. package/pennyfarthing_scripts/jira_epic_creation.py +30 -0
  270. package/pennyfarthing_scripts/jira_sync.py +36 -0
  271. package/pennyfarthing_scripts/jira_sync_story.py +30 -0
  272. package/pennyfarthing_scripts/migration/__init__.py +39 -0
  273. package/pennyfarthing_scripts/migration/__main__.py +10 -0
  274. package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
  275. package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
  276. package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
  277. package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
  278. package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
  279. package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
  280. package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
  281. package/pennyfarthing_scripts/migration/cli.py +304 -0
  282. package/pennyfarthing_scripts/migration/session.py +384 -0
  283. package/pennyfarthing_scripts/migration/skill.py +188 -0
  284. package/pennyfarthing_scripts/migration/step.py +229 -0
  285. package/pennyfarthing_scripts/migration/validate.py +282 -0
  286. package/pennyfarthing_scripts/output.py +37 -0
  287. package/pennyfarthing_scripts/patch_mode.py +449 -0
  288. package/pennyfarthing_scripts/preflight/__init__.py +17 -0
  289. package/pennyfarthing_scripts/preflight/__main__.py +10 -0
  290. package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
  291. package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
  292. package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
  293. package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
  294. package/pennyfarthing_scripts/preflight/cli.py +141 -0
  295. package/pennyfarthing_scripts/preflight/finish.py +382 -0
  296. package/pennyfarthing_scripts/pretooluse_hook.py +193 -0
  297. package/pennyfarthing_scripts/prime/__init__.py +125 -0
  298. package/pennyfarthing_scripts/prime/__main__.py +8 -0
  299. package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
  300. package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
  301. package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
  302. package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
  303. package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
  304. package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
  305. package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
  306. package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
  307. package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
  308. package/pennyfarthing_scripts/prime/cli.py +645 -0
  309. package/pennyfarthing_scripts/prime/loader.py +239 -0
  310. package/pennyfarthing_scripts/prime/models.py +206 -0
  311. package/pennyfarthing_scripts/prime/persona.py +309 -0
  312. package/pennyfarthing_scripts/prime/session.py +183 -0
  313. package/pennyfarthing_scripts/prime/tiers.py +201 -0
  314. package/pennyfarthing_scripts/prime/workflow.py +275 -0
  315. package/pennyfarthing_scripts/schema_validation_hook.py +306 -0
  316. package/pennyfarthing_scripts/sprint/__init__.py +66 -0
  317. package/pennyfarthing_scripts/sprint/__main__.py +10 -0
  318. package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
  319. package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
  320. package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
  321. package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
  322. package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
  323. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  324. package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
  325. package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
  326. package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
  327. package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
  328. package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
  329. package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
  330. package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
  331. package/pennyfarthing_scripts/sprint/archive.py +108 -0
  332. package/pennyfarthing_scripts/sprint/archive_epic.py +399 -0
  333. package/pennyfarthing_scripts/sprint/cli.py +373 -0
  334. package/pennyfarthing_scripts/sprint/import_epic.py +431 -0
  335. package/pennyfarthing_scripts/sprint/loader.py +193 -0
  336. package/pennyfarthing_scripts/sprint/status.py +122 -0
  337. package/pennyfarthing_scripts/sprint/story_add.py +187 -0
  338. package/pennyfarthing_scripts/sprint/story_update.py +181 -0
  339. package/pennyfarthing_scripts/sprint/validate_cmd.py +268 -0
  340. package/pennyfarthing_scripts/sprint/validator.py +570 -0
  341. package/pennyfarthing_scripts/sprint/work.py +192 -0
  342. package/pennyfarthing_scripts/sprint/yaml_io.py +258 -0
  343. package/pennyfarthing_scripts/story/__init__.py +67 -0
  344. package/pennyfarthing_scripts/story/__main__.py +10 -0
  345. package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
  346. package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
  347. package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
  348. package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
  349. package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
  350. package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
  351. package/pennyfarthing_scripts/story/cli.py +105 -0
  352. package/pennyfarthing_scripts/story/create.py +167 -0
  353. package/pennyfarthing_scripts/story/size.py +113 -0
  354. package/pennyfarthing_scripts/story/template.py +151 -0
  355. package/pennyfarthing_scripts/swebench.py +216 -0
  356. package/pennyfarthing_scripts/tests/__init__.py +1 -0
  357. package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  358. package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  359. package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
  360. package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
  361. package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
  362. package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
  363. package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
  364. package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
  365. package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
  366. package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
  367. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
  368. package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
  369. package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
  370. package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
  371. package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
  372. package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
  373. package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
  374. package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
  375. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  376. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  377. package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
  378. package/pennyfarthing_scripts/tests/conftest.py +106 -0
  379. package/pennyfarthing_scripts/tests/test_brownfield.py +842 -0
  380. package/pennyfarthing_scripts/tests/test_cli_modules.py +245 -0
  381. package/pennyfarthing_scripts/tests/test_common.py +180 -0
  382. package/pennyfarthing_scripts/tests/test_git_utils.py +866 -0
  383. package/pennyfarthing_scripts/tests/test_jira_package.py +334 -0
  384. package/pennyfarthing_scripts/tests/test_package_structure.py +372 -0
  385. package/pennyfarthing_scripts/tests/test_patch_mode.py +830 -0
  386. package/pennyfarthing_scripts/tests/test_prime.py +1050 -0
  387. package/pennyfarthing_scripts/tests/test_sprint_package.py +236 -0
  388. package/pennyfarthing_scripts/tests/test_sprint_validator.py +731 -0
  389. package/pennyfarthing_scripts/tests/test_story_add.py +921 -0
  390. package/pennyfarthing_scripts/tests/test_story_package.py +156 -0
  391. package/pennyfarthing_scripts/tests/test_story_update.py +769 -0
  392. package/pennyfarthing_scripts/tests/test_tiers.py +1090 -0
  393. package/pennyfarthing_scripts/tests/test_token_counting.py +559 -0
  394. package/pennyfarthing_scripts/tests/test_validate_cmd.py +500 -0
  395. package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
  396. package/pennyfarthing_scripts/tests/test_yaml_io.py +698 -0
  397. package/pennyfarthing_scripts/welcome_hook.py +157 -0
  398. package/pennyfarthing_scripts/workflow.py +287 -0
  399. package/dist/cli/commands/doctor.js.map +0 -1
  400. package/dist/cli/utils/settings.js.map +0 -1
  401. package/dist/cli/utils/themes.d.ts.map +0 -1
  402. package/pennyfarthing-dist/scripts/jira/jira-lib.sh +0 -464
  403. package/pennyfarthing-dist/scripts/jira/jira-sync.sh +0 -16
  404. package/pennyfarthing-dist/scripts/jira/sync-epic-to-jira.sh +0 -16
  405. /package/{bin → packages/core/bin}/pennyfarthing.js +0 -0
  406. /package/{dist → packages/core/dist}/bmad/context-reader.d.ts +0 -0
  407. /package/{dist → packages/core/dist}/bmad/context-reader.d.ts.map +0 -0
  408. /package/{dist → packages/core/dist}/bmad/context-reader.js +0 -0
  409. /package/{dist → packages/core/dist}/bmad/context-reader.js.map +0 -0
  410. /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts +0 -0
  411. /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts.map +0 -0
  412. /package/{dist → packages/core/dist}/bmad/context-reader.test.js +0 -0
  413. /package/{dist → packages/core/dist}/bmad/context-reader.test.js.map +0 -0
  414. /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts +0 -0
  415. /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts.map +0 -0
  416. /package/{dist → packages/core/dist}/bmad/epics-parser.js +0 -0
  417. /package/{dist → packages/core/dist}/bmad/epics-parser.js.map +0 -0
  418. /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts +0 -0
  419. /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts.map +0 -0
  420. /package/{dist → packages/core/dist}/bmad/epics-parser.test.js +0 -0
  421. /package/{dist → packages/core/dist}/bmad/epics-parser.test.js.map +0 -0
  422. /package/{dist → packages/core/dist}/bmad/index.d.ts +0 -0
  423. /package/{dist → packages/core/dist}/bmad/index.d.ts.map +0 -0
  424. /package/{dist → packages/core/dist}/bmad/index.js +0 -0
  425. /package/{dist → packages/core/dist}/bmad/index.js.map +0 -0
  426. /package/{dist → packages/core/dist}/bmad/status-sync.d.ts +0 -0
  427. /package/{dist → packages/core/dist}/bmad/status-sync.d.ts.map +0 -0
  428. /package/{dist → packages/core/dist}/bmad/status-sync.js +0 -0
  429. /package/{dist → packages/core/dist}/bmad/status-sync.js.map +0 -0
  430. /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts +0 -0
  431. /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts.map +0 -0
  432. /package/{dist → packages/core/dist}/bmad/status-sync.test.js +0 -0
  433. /package/{dist → packages/core/dist}/bmad/status-sync.test.js.map +0 -0
  434. /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts +0 -0
  435. /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts.map +0 -0
  436. /package/{dist → packages/core/dist}/bmad/story-exporter.js +0 -0
  437. /package/{dist → packages/core/dist}/bmad/story-exporter.js.map +0 -0
  438. /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts +0 -0
  439. /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts.map +0 -0
  440. /package/{dist → packages/core/dist}/bmad/story-exporter.test.js +0 -0
  441. /package/{dist → packages/core/dist}/bmad/story-exporter.test.js.map +0 -0
  442. /package/{dist → packages/core/dist}/bmad/story-parser.d.ts +0 -0
  443. /package/{dist → packages/core/dist}/bmad/story-parser.d.ts.map +0 -0
  444. /package/{dist → packages/core/dist}/bmad/story-parser.js +0 -0
  445. /package/{dist → packages/core/dist}/bmad/story-parser.js.map +0 -0
  446. /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts +0 -0
  447. /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts.map +0 -0
  448. /package/{dist → packages/core/dist}/bmad/story-parser.test.js +0 -0
  449. /package/{dist → packages/core/dist}/bmad/story-parser.test.js.map +0 -0
  450. /package/{dist → packages/core/dist}/cli/commands/command.d.ts +0 -0
  451. /package/{dist → packages/core/dist}/cli/commands/command.d.ts.map +0 -0
  452. /package/{dist → packages/core/dist}/cli/commands/command.js +0 -0
  453. /package/{dist → packages/core/dist}/cli/commands/command.js.map +0 -0
  454. /package/{dist → packages/core/dist}/cli/commands/cyclist.d.ts +0 -0
  455. /package/{dist → packages/core/dist}/cli/commands/cyclist.d.ts.map +0 -0
  456. /package/{dist → packages/core/dist}/cli/commands/cyclist.js +0 -0
  457. /package/{dist → packages/core/dist}/cli/commands/cyclist.js.map +0 -0
  458. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts +0 -0
  459. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts.map +0 -0
  460. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.js +0 -0
  461. /package/{dist → packages/core/dist}/cli/commands/cyclist.test.js.map +0 -0
  462. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts +0 -0
  463. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts.map +0 -0
  464. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js +0 -0
  465. /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js.map +0 -0
  466. /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts +0 -0
  467. /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts.map +0 -0
  468. /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts +0 -0
  469. /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts.map +0 -0
  470. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts +0 -0
  471. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts.map +0 -0
  472. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js +0 -0
  473. /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js.map +0 -0
  474. /package/{dist → packages/core/dist}/cli/commands/init.d.ts +0 -0
  475. /package/{dist → packages/core/dist}/cli/commands/init.d.ts.map +0 -0
  476. /package/{dist → packages/core/dist}/cli/commands/init.js +0 -0
  477. /package/{dist → packages/core/dist}/cli/commands/init.js.map +0 -0
  478. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts +0 -0
  479. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts.map +0 -0
  480. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js +0 -0
  481. /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js.map +0 -0
  482. /package/{dist → packages/core/dist}/cli/commands/skill.d.ts +0 -0
  483. /package/{dist → packages/core/dist}/cli/commands/skill.d.ts.map +0 -0
  484. /package/{dist → packages/core/dist}/cli/commands/skill.js +0 -0
  485. /package/{dist → packages/core/dist}/cli/commands/skill.js.map +0 -0
  486. /package/{dist → packages/core/dist}/cli/commands/theme.d.ts +0 -0
  487. /package/{dist → packages/core/dist}/cli/commands/theme.d.ts.map +0 -0
  488. /package/{dist → packages/core/dist}/cli/commands/theme.js +0 -0
  489. /package/{dist → packages/core/dist}/cli/commands/theme.js.map +0 -0
  490. /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts +0 -0
  491. /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts.map +0 -0
  492. /package/{dist → packages/core/dist}/cli/commands/uninstall.js +0 -0
  493. /package/{dist → packages/core/dist}/cli/commands/uninstall.js.map +0 -0
  494. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts +0 -0
  495. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts.map +0 -0
  496. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js +0 -0
  497. /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js.map +0 -0
  498. /package/{dist → packages/core/dist}/cli/commands/update.d.ts +0 -0
  499. /package/{dist → packages/core/dist}/cli/commands/version.d.ts +0 -0
  500. /package/{dist → packages/core/dist}/cli/commands/version.d.ts.map +0 -0
  501. /package/{dist → packages/core/dist}/cli/commands/version.js +0 -0
  502. /package/{dist → packages/core/dist}/cli/commands/version.js.map +0 -0
  503. /package/{dist → packages/core/dist}/cli/customization.test.d.ts +0 -0
  504. /package/{dist → packages/core/dist}/cli/customization.test.d.ts.map +0 -0
  505. /package/{dist → packages/core/dist}/cli/customization.test.js +0 -0
  506. /package/{dist → packages/core/dist}/cli/customization.test.js.map +0 -0
  507. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts +0 -0
  508. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts.map +0 -0
  509. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js +0 -0
  510. /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js.map +0 -0
  511. /package/{dist → packages/core/dist}/cli/index.d.ts +0 -0
  512. /package/{dist → packages/core/dist}/cli/index.d.ts.map +0 -0
  513. /package/{dist → packages/core/dist}/cli/index.js +0 -0
  514. /package/{dist → packages/core/dist}/cli/index.js.map +0 -0
  515. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts +0 -0
  516. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts.map +0 -0
  517. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.js +0 -0
  518. /package/{dist → packages/core/dist}/cli/ocean-profiles.test.js.map +0 -0
  519. /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts +0 -0
  520. /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts.map +0 -0
  521. /package/{dist → packages/core/dist}/cli/theme-maker.test.js +0 -0
  522. /package/{dist → packages/core/dist}/cli/theme-maker.test.js.map +0 -0
  523. /package/{dist → packages/core/dist}/cli/utils/constants.d.ts +0 -0
  524. /package/{dist → packages/core/dist}/cli/utils/constants.d.ts.map +0 -0
  525. /package/{dist → packages/core/dist}/cli/utils/constants.js +0 -0
  526. /package/{dist → packages/core/dist}/cli/utils/constants.js.map +0 -0
  527. /package/{dist → packages/core/dist}/cli/utils/files.d.ts +0 -0
  528. /package/{dist → packages/core/dist}/cli/utils/files.d.ts.map +0 -0
  529. /package/{dist → packages/core/dist}/cli/utils/files.js +0 -0
  530. /package/{dist → packages/core/dist}/cli/utils/files.js.map +0 -0
  531. /package/{dist → packages/core/dist}/cli/utils/logger.d.ts +0 -0
  532. /package/{dist → packages/core/dist}/cli/utils/logger.d.ts.map +0 -0
  533. /package/{dist → packages/core/dist}/cli/utils/logger.js +0 -0
  534. /package/{dist → packages/core/dist}/cli/utils/logger.js.map +0 -0
  535. /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts +0 -0
  536. /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts.map +0 -0
  537. /package/{dist → packages/core/dist}/cli/utils/manifest.js +0 -0
  538. /package/{dist → packages/core/dist}/cli/utils/manifest.js.map +0 -0
  539. /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts +0 -0
  540. /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts.map +0 -0
  541. /package/{dist → packages/core/dist}/cli/utils/node-modules.js +0 -0
  542. /package/{dist → packages/core/dist}/cli/utils/node-modules.js.map +0 -0
  543. /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts +0 -0
  544. /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts.map +0 -0
  545. /package/{dist → packages/core/dist}/cli/utils/prompts.js +0 -0
  546. /package/{dist → packages/core/dist}/cli/utils/prompts.js.map +0 -0
  547. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts +0 -0
  548. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts.map +0 -0
  549. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js +0 -0
  550. /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js.map +0 -0
  551. /package/{dist → packages/core/dist}/cli/utils/settings.d.ts +0 -0
  552. /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts +0 -0
  553. /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts.map +0 -0
  554. /package/{dist → packages/core/dist}/cli/utils/symlinks.js +0 -0
  555. /package/{dist → packages/core/dist}/cli/utils/symlinks.js.map +0 -0
  556. /package/{dist → packages/core/dist}/cli/utils/themes.js +0 -0
  557. /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts +0 -0
  558. /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts.map +0 -0
  559. /package/{dist → packages/core/dist}/cli/utils/themes.test.js +0 -0
  560. /package/{dist → packages/core/dist}/cli/utils/themes.test.js.map +0 -0
  561. /package/{dist → packages/core/dist}/cli/utils/version.d.ts +0 -0
  562. /package/{dist → packages/core/dist}/cli/utils/version.d.ts.map +0 -0
  563. /package/{dist → packages/core/dist}/cli/utils/version.js +0 -0
  564. /package/{dist → packages/core/dist}/cli/utils/version.js.map +0 -0
  565. /package/{dist → packages/core/dist}/cli/workspace.test.d.ts +0 -0
  566. /package/{dist → packages/core/dist}/cli/workspace.test.d.ts.map +0 -0
  567. /package/{dist → packages/core/dist}/cli/workspace.test.js +0 -0
  568. /package/{dist → packages/core/dist}/cli/workspace.test.js.map +0 -0
  569. /package/{dist → packages/core/dist}/index.d.ts +0 -0
  570. /package/{dist → packages/core/dist}/index.d.ts.map +0 -0
  571. /package/{dist → packages/core/dist}/index.js +0 -0
  572. /package/{dist → packages/core/dist}/index.js.map +0 -0
  573. /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts +0 -0
  574. /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts.map +0 -0
  575. /package/{dist → packages/core/dist}/jira/jira-epic-creation.js +0 -0
  576. /package/{dist → packages/core/dist}/jira/jira-epic-creation.js.map +0 -0
  577. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts +0 -0
  578. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts.map +0 -0
  579. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js +0 -0
  580. /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js.map +0 -0
  581. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts +0 -0
  582. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts.map +0 -0
  583. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js +0 -0
  584. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js.map +0 -0
  585. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts +0 -0
  586. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts.map +0 -0
  587. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js +0 -0
  588. /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js.map +0 -0
  589. /package/{dist → packages/core/dist}/permissions/index.d.ts +0 -0
  590. /package/{dist → packages/core/dist}/permissions/index.d.ts.map +0 -0
  591. /package/{dist → packages/core/dist}/permissions/index.js +0 -0
  592. /package/{dist → packages/core/dist}/permissions/index.js.map +0 -0
  593. /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts +0 -0
  594. /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts.map +0 -0
  595. /package/{dist → packages/core/dist}/permissions/permission-schema.js +0 -0
  596. /package/{dist → packages/core/dist}/permissions/permission-schema.js.map +0 -0
  597. /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts +0 -0
  598. /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts.map +0 -0
  599. /package/{dist → packages/core/dist}/permissions/permission-schema.test.js +0 -0
  600. /package/{dist → packages/core/dist}/permissions/permission-schema.test.js.map +0 -0
  601. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts +0 -0
  602. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts.map +0 -0
  603. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js +0 -0
  604. /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js.map +0 -0
  605. /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts +0 -0
  606. /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts.map +0 -0
  607. /package/{dist → packages/core/dist}/scripts/benchmark-integration.js +0 -0
  608. /package/{dist → packages/core/dist}/scripts/benchmark-integration.js.map +0 -0
  609. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts +0 -0
  610. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts.map +0 -0
  611. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js +0 -0
  612. /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js.map +0 -0
  613. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts +0 -0
  614. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts.map +0 -0
  615. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js +0 -0
  616. /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js.map +0 -0
  617. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts +0 -0
  618. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts.map +0 -0
  619. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js +0 -0
  620. /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js.map +0 -0
  621. /package/{dist → packages/core/dist}/scripts/generate-report.d.ts +0 -0
  622. /package/{dist → packages/core/dist}/scripts/generate-report.d.ts.map +0 -0
  623. /package/{dist → packages/core/dist}/scripts/generate-report.js +0 -0
  624. /package/{dist → packages/core/dist}/scripts/generate-report.js.map +0 -0
  625. /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts +0 -0
  626. /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts.map +0 -0
  627. /package/{dist → packages/core/dist}/scripts/generate-report.test.js +0 -0
  628. /package/{dist → packages/core/dist}/scripts/generate-report.test.js.map +0 -0
  629. /package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts +0 -0
  630. /package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts.map +0 -0
  631. /package/{dist → packages/core/dist}/scripts/generate-spider-report.js +0 -0
  632. /package/{dist → packages/core/dist}/scripts/generate-spider-report.js.map +0 -0
  633. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts +0 -0
  634. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts.map +0 -0
  635. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js +0 -0
  636. /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js.map +0 -0
  637. /package/{dist → packages/core/dist}/scripts/generate-spider.d.ts +0 -0
  638. /package/{dist → packages/core/dist}/scripts/generate-spider.d.ts.map +0 -0
  639. /package/{dist → packages/core/dist}/scripts/generate-spider.js +0 -0
  640. /package/{dist → packages/core/dist}/scripts/generate-spider.js.map +0 -0
  641. /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts +0 -0
  642. /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts.map +0 -0
  643. /package/{dist → packages/core/dist}/scripts/generate-spider.test.js +0 -0
  644. /package/{dist → packages/core/dist}/scripts/generate-spider.test.js.map +0 -0
  645. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts +0 -0
  646. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts.map +0 -0
  647. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js +0 -0
  648. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js.map +0 -0
  649. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts +0 -0
  650. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts.map +0 -0
  651. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js +0 -0
  652. /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js.map +0 -0
  653. /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts +0 -0
  654. /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts.map +0 -0
  655. /package/{dist → packages/core/dist}/scripts/run-ci.test.js +0 -0
  656. /package/{dist → packages/core/dist}/scripts/run-ci.test.js.map +0 -0
  657. /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts +0 -0
  658. /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts.map +0 -0
  659. /package/{dist → packages/core/dist}/scripts/theme-detail.test.js +0 -0
  660. /package/{dist → packages/core/dist}/scripts/theme-detail.test.js.map +0 -0
  661. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts +0 -0
  662. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts.map +0 -0
  663. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js +0 -0
  664. /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js.map +0 -0
  665. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts +0 -0
  666. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts.map +0 -0
  667. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js +0 -0
  668. /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js.map +0 -0
  669. /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts +0 -0
  670. /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts.map +0 -0
  671. /package/{dist → packages/core/dist}/workflow/gate-handler.js +0 -0
  672. /package/{dist → packages/core/dist}/workflow/gate-handler.js.map +0 -0
  673. /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts +0 -0
  674. /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts.map +0 -0
  675. /package/{dist → packages/core/dist}/workflow/gate-handler.test.js +0 -0
  676. /package/{dist → packages/core/dist}/workflow/gate-handler.test.js.map +0 -0
  677. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts +0 -0
  678. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts.map +0 -0
  679. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js +0 -0
  680. /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js.map +0 -0
  681. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts +0 -0
  682. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts.map +0 -0
  683. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js +0 -0
  684. /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js.map +0 -0
  685. /package/{dist → packages/core/dist}/workflow/handoff.d.ts +0 -0
  686. /package/{dist → packages/core/dist}/workflow/handoff.d.ts.map +0 -0
  687. /package/{dist → packages/core/dist}/workflow/handoff.js +0 -0
  688. /package/{dist → packages/core/dist}/workflow/handoff.js.map +0 -0
  689. /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts +0 -0
  690. /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts.map +0 -0
  691. /package/{dist → packages/core/dist}/workflow/handoff.test.js +0 -0
  692. /package/{dist → packages/core/dist}/workflow/handoff.test.js.map +0 -0
  693. /package/{dist → packages/core/dist}/workflow/index.d.ts +0 -0
  694. /package/{dist → packages/core/dist}/workflow/index.d.ts.map +0 -0
  695. /package/{dist → packages/core/dist}/workflow/index.js +0 -0
  696. /package/{dist → packages/core/dist}/workflow/index.js.map +0 -0
  697. /package/{dist → packages/core/dist}/workflow/session-state.d.ts +0 -0
  698. /package/{dist → packages/core/dist}/workflow/session-state.d.ts.map +0 -0
  699. /package/{dist → packages/core/dist}/workflow/session-state.js +0 -0
  700. /package/{dist → packages/core/dist}/workflow/session-state.js.map +0 -0
  701. /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts +0 -0
  702. /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts.map +0 -0
  703. /package/{dist → packages/core/dist}/workflow/session-state.test.js +0 -0
  704. /package/{dist → packages/core/dist}/workflow/session-state.test.js.map +0 -0
  705. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts +0 -0
  706. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts.map +0 -0
  707. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js +0 -0
  708. /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js.map +0 -0
  709. /package/{dist → packages/core/dist}/workflow/step-parser.d.ts +0 -0
  710. /package/{dist → packages/core/dist}/workflow/step-parser.d.ts.map +0 -0
  711. /package/{dist → packages/core/dist}/workflow/step-parser.js +0 -0
  712. /package/{dist → packages/core/dist}/workflow/step-parser.js.map +0 -0
  713. /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts +0 -0
  714. /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts.map +0 -0
  715. /package/{dist → packages/core/dist}/workflow/step-parser.test.js +0 -0
  716. /package/{dist → packages/core/dist}/workflow/step-parser.test.js.map +0 -0
  717. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts +0 -0
  718. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts.map +0 -0
  719. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js +0 -0
  720. /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js.map +0 -0
  721. /package/{dist → packages/core/dist}/workflow/test-cache.d.ts +0 -0
  722. /package/{dist → packages/core/dist}/workflow/test-cache.d.ts.map +0 -0
  723. /package/{dist → packages/core/dist}/workflow/test-cache.js +0 -0
  724. /package/{dist → packages/core/dist}/workflow/test-cache.js.map +0 -0
  725. /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts +0 -0
  726. /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts.map +0 -0
  727. /package/{dist → packages/core/dist}/workflow/test-cache.test.js +0 -0
  728. /package/{dist → packages/core/dist}/workflow/test-cache.test.js.map +0 -0
  729. /package/{dist → packages/core/dist}/workflow/trimodal.d.ts +0 -0
  730. /package/{dist → packages/core/dist}/workflow/trimodal.d.ts.map +0 -0
  731. /package/{dist → packages/core/dist}/workflow/trimodal.js +0 -0
  732. /package/{dist → packages/core/dist}/workflow/trimodal.js.map +0 -0
  733. /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts +0 -0
  734. /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts.map +0 -0
  735. /package/{dist → packages/core/dist}/workflow/trimodal.test.js +0 -0
  736. /package/{dist → packages/core/dist}/workflow/trimodal.test.js.map +0 -0
  737. /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts +0 -0
  738. /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts.map +0 -0
  739. /package/{dist → packages/core/dist}/workflow/variable-resolver.js +0 -0
  740. /package/{dist → packages/core/dist}/workflow/variable-resolver.js.map +0 -0
  741. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts +0 -0
  742. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts.map +0 -0
  743. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js +0 -0
  744. /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js.map +0 -0
  745. /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts +0 -0
  746. /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts.map +0 -0
  747. /package/{dist → packages/core/dist}/workflow/workflow-executor.js +0 -0
  748. /package/{dist → packages/core/dist}/workflow/workflow-executor.js.map +0 -0
  749. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts +0 -0
  750. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts.map +0 -0
  751. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js +0 -0
  752. /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js.map +0 -0
  753. /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts +0 -0
  754. /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts.map +0 -0
  755. /package/{dist → packages/core/dist}/workflow/workflow-loader.js +0 -0
  756. /package/{dist → packages/core/dist}/workflow/workflow-loader.js.map +0 -0
  757. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts +0 -0
  758. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts.map +0 -0
  759. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js +0 -0
  760. /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js.map +0 -0
  761. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts +0 -0
  762. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts.map +0 -0
  763. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js +0 -0
  764. /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js.map +0 -0
  765. /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts +0 -0
  766. /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts.map +0 -0
  767. /package/{dist → packages/core/dist}/workflow/workflow-permissions.js +0 -0
  768. /package/{dist → packages/core/dist}/workflow/workflow-permissions.js.map +0 -0
  769. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts +0 -0
  770. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts.map +0 -0
  771. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js +0 -0
  772. /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js.map +0 -0
  773. /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts +0 -0
  774. /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts.map +0 -0
  775. /package/{dist → packages/core/dist}/workflow/workflow-router.js +0 -0
  776. /package/{dist → packages/core/dist}/workflow/workflow-router.js.map +0 -0
  777. /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts +0 -0
  778. /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts.map +0 -0
  779. /package/{dist → packages/core/dist}/workflow/workflow-router.test.js +0 -0
  780. /package/{dist → packages/core/dist}/workflow/workflow-router.test.js.map +0 -0
  781. /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts +0 -0
  782. /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts.map +0 -0
  783. /package/{dist → packages/core/dist}/workflow/workflow-schema.js +0 -0
  784. /package/{dist → packages/core/dist}/workflow/workflow-schema.js.map +0 -0
  785. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts +0 -0
  786. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts.map +0 -0
  787. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js +0 -0
  788. /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js.map +0 -0
  789. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts +0 -0
  790. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts.map +0 -0
  791. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js +0 -0
  792. /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js.map +0 -0
@@ -0,0 +1,921 @@
1
+ """Tests for sprint/story_add.py module.
2
+
3
+ Story: MSSCI-14256 - Sprint story add command
4
+
5
+ TDD RED phase: All tests should FAIL until implementation.
6
+
7
+ Acceptance Criteria:
8
+ 1. Auto-generates next story ID within epic (max+1, no gap-fill)
9
+ 2. Validates target epic exists before insertion
10
+ 3. Populates required fields with defaults, optional fields only when provided
11
+ 4. Appends story at end of epic's stories list as CommentedMap
12
+ 5. Validates entire sprint file after insertion, aborts on failure
13
+ 6. CLI: /sprint story add <epic_id> <title> <points> with options
14
+ 7. Edge cases: YAML-special chars, first story, sequence gaps
15
+ """
16
+
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import pytest
21
+ from click.testing import CliRunner
22
+ from ruamel.yaml.comments import CommentedMap, CommentedSeq
23
+
24
+ from pennyfarthing_scripts.sprint.story_add import (
25
+ add_story,
26
+ generate_story_id,
27
+ )
28
+ from pennyfarthing_scripts.sprint.yaml_io import (
29
+ STORY_KEY_ORDER,
30
+ read_sprint,
31
+ write_sprint,
32
+ )
33
+
34
+
35
+ # =============================================================================
36
+ # Test Fixtures
37
+ # =============================================================================
38
+
39
+
40
+ MINIMAL_SPRINT_YAML = """\
41
+ sprint:
42
+ name: "TO Sprint 2604"
43
+ jira_sprint_id: 276
44
+ jira_sprint_name: "TO Sprint 2604"
45
+ goal: Complete the sprint
46
+ start_date: 2026-01-20
47
+ end_date: 2026-02-02
48
+ status: active
49
+ number: 2604
50
+ epics:
51
+ - id: epic-76
52
+ type: epic
53
+ title: "Epic: Sprint Data Management"
54
+ priority: P1
55
+ status: in_progress
56
+ jira: MSSCI-14253
57
+ stories:
58
+ - id: 76-1
59
+ title: Core yaml_io module
60
+ points: 3
61
+ priority: P0
62
+ status: done
63
+ workflow: tdd
64
+ - id: 76-2
65
+ title: Sprint validate command
66
+ points: 2
67
+ priority: P0
68
+ status: done
69
+ workflow: tdd
70
+ """
71
+
72
+ MULTI_EPIC_YAML = """\
73
+ sprint:
74
+ name: "TO Sprint 2604"
75
+ jira_sprint_id: 276
76
+ jira_sprint_name: "TO Sprint 2604"
77
+ goal: Complete the sprint
78
+ start_date: 2026-01-20
79
+ end_date: 2026-02-02
80
+ status: active
81
+ number: 2604
82
+ epics:
83
+ - id: epic-76
84
+ type: epic
85
+ title: "Epic: Sprint Data Management"
86
+ priority: P1
87
+ status: in_progress
88
+ jira: MSSCI-14253
89
+ stories:
90
+ - id: 76-1
91
+ title: Core yaml_io module
92
+ points: 3
93
+ priority: P0
94
+ status: done
95
+ workflow: tdd
96
+ - id: epic-77
97
+ type: epic
98
+ title: "Epic: Another Feature"
99
+ priority: P1
100
+ status: in_progress
101
+ jira: MSSCI-14300
102
+ stories:
103
+ - id: 77-1
104
+ title: First task
105
+ points: 2
106
+ priority: P1
107
+ status: backlog
108
+ workflow: trivial
109
+ """
110
+
111
+ EMPTY_STORIES_YAML = """\
112
+ sprint:
113
+ name: "TO Sprint 2604"
114
+ jira_sprint_id: 276
115
+ jira_sprint_name: "TO Sprint 2604"
116
+ goal: Complete the sprint
117
+ start_date: 2026-01-20
118
+ end_date: 2026-02-02
119
+ status: active
120
+ number: 2604
121
+ epics:
122
+ - id: epic-80
123
+ type: epic
124
+ title: "Epic: Brand New"
125
+ priority: P1
126
+ status: in_progress
127
+ jira: MSSCI-15000
128
+ stories: []
129
+ """
130
+
131
+ GAPPED_IDS_YAML = """\
132
+ sprint:
133
+ name: "TO Sprint 2604"
134
+ jira_sprint_id: 276
135
+ jira_sprint_name: "TO Sprint 2604"
136
+ goal: Complete the sprint
137
+ start_date: 2026-01-20
138
+ end_date: 2026-02-02
139
+ status: active
140
+ number: 2604
141
+ epics:
142
+ - id: epic-50
143
+ type: epic
144
+ title: "Epic: Gapped IDs"
145
+ priority: P1
146
+ status: in_progress
147
+ jira: MSSCI-11000
148
+ stories:
149
+ - id: 50-1
150
+ title: First story
151
+ points: 2
152
+ priority: P1
153
+ status: done
154
+ workflow: tdd
155
+ - id: 50-3
156
+ title: Third story (gap at 2)
157
+ points: 3
158
+ priority: P1
159
+ status: done
160
+ workflow: tdd
161
+ - id: 50-5
162
+ title: Fifth story (gap at 4)
163
+ points: 1
164
+ priority: P2
165
+ status: backlog
166
+ workflow: trivial
167
+ """
168
+
169
+
170
+ @pytest.fixture
171
+ def sprint_file(tmp_path: Path) -> Path:
172
+ """Create a sprint YAML file with one epic and two stories."""
173
+ p = tmp_path / "current-sprint.yaml"
174
+ p.write_text(MINIMAL_SPRINT_YAML)
175
+ return p
176
+
177
+
178
+ @pytest.fixture
179
+ def multi_epic_file(tmp_path: Path) -> Path:
180
+ """Create a sprint YAML file with multiple epics."""
181
+ p = tmp_path / "current-sprint.yaml"
182
+ p.write_text(MULTI_EPIC_YAML)
183
+ return p
184
+
185
+
186
+ @pytest.fixture
187
+ def empty_stories_file(tmp_path: Path) -> Path:
188
+ """Create a sprint YAML file with an epic that has no stories."""
189
+ p = tmp_path / "current-sprint.yaml"
190
+ p.write_text(EMPTY_STORIES_YAML)
191
+ return p
192
+
193
+
194
+ @pytest.fixture
195
+ def gapped_ids_file(tmp_path: Path) -> Path:
196
+ """Create a sprint YAML file with non-sequential story IDs."""
197
+ p = tmp_path / "current-sprint.yaml"
198
+ p.write_text(GAPPED_IDS_YAML)
199
+ return p
200
+
201
+
202
+ @pytest.fixture
203
+ def runner() -> CliRunner:
204
+ """Create a Click test runner."""
205
+ return CliRunner()
206
+
207
+
208
+ # =============================================================================
209
+ # AC1: Story ID Generation
210
+ # =============================================================================
211
+
212
+
213
+ class TestIDGeneration:
214
+ """Auto-generates next story ID within epic (max+1, no gap-fill)."""
215
+
216
+ def test_next_id_after_existing_stories(self, sprint_file: Path) -> None:
217
+ """With stories 76-1 and 76-2, next ID should be 76-3."""
218
+ data = read_sprint(sprint_file)
219
+ epic = data["epics"][0]
220
+
221
+ story_id = generate_story_id(data, epic)
222
+
223
+ assert story_id == "76-3"
224
+
225
+ def test_first_story_in_empty_epic(self, empty_stories_file: Path) -> None:
226
+ """With no stories, first ID should be <epic_num>-1."""
227
+ data = read_sprint(empty_stories_file)
228
+ epic = data["epics"][0]
229
+
230
+ story_id = generate_story_id(data, epic)
231
+
232
+ assert story_id == "80-1"
233
+
234
+ def test_uses_max_plus_one_with_gaps(self, gapped_ids_file: Path) -> None:
235
+ """With IDs 50-1, 50-3, 50-5, next should be 50-6 (not 50-2)."""
236
+ data = read_sprint(gapped_ids_file)
237
+ epic = data["epics"][0]
238
+
239
+ story_id = generate_story_id(data, epic)
240
+
241
+ assert story_id == "50-6"
242
+
243
+ def test_generated_id_unique_across_epics(self, multi_epic_file: Path) -> None:
244
+ """Generated ID must not collide with IDs in other epics."""
245
+ data = read_sprint(multi_epic_file)
246
+ epic = data["epics"][0] # epic-76
247
+
248
+ story_id = generate_story_id(data, epic)
249
+
250
+ # Collect all existing IDs across all epics
251
+ all_ids = set()
252
+ for e in data["epics"]:
253
+ for s in e.get("stories", []):
254
+ all_ids.add(s["id"])
255
+
256
+ assert story_id not in all_ids
257
+
258
+ def test_extracts_epic_num_from_epic_prefix(self, sprint_file: Path) -> None:
259
+ """Should handle epic IDs like 'epic-76' correctly."""
260
+ data = read_sprint(sprint_file)
261
+ epic = data["epics"][0]
262
+
263
+ # epic ID is "epic-76"
264
+ story_id = generate_story_id(data, epic)
265
+
266
+ # Should use numeric part "76" as prefix
267
+ assert story_id.startswith("76-")
268
+
269
+
270
+ # =============================================================================
271
+ # AC2: Epic Validation
272
+ # =============================================================================
273
+
274
+
275
+ class TestEpicValidation:
276
+ """Validates target epic exists before insertion."""
277
+
278
+ def test_add_to_existing_epic(self, sprint_file: Path) -> None:
279
+ """Adding a story to an existing epic should succeed."""
280
+ result = add_story(
281
+ sprint_path=sprint_file,
282
+ epic_id="76",
283
+ title="New story",
284
+ points=3,
285
+ )
286
+
287
+ assert result["success"] is True
288
+
289
+ def test_add_to_nonexistent_epic_fails(self, sprint_file: Path) -> None:
290
+ """Adding a story to a non-existent epic should fail with clear error."""
291
+ result = add_story(
292
+ sprint_path=sprint_file,
293
+ epic_id="999",
294
+ title="New story",
295
+ points=3,
296
+ )
297
+
298
+ assert result["success"] is False
299
+ assert "error" in result
300
+ assert "999" in result["error"]
301
+
302
+ def test_error_lists_available_epics(self, multi_epic_file: Path) -> None:
303
+ """Error for missing epic should list available epic IDs."""
304
+ result = add_story(
305
+ sprint_path=multi_epic_file,
306
+ epic_id="999",
307
+ title="New story",
308
+ points=3,
309
+ )
310
+
311
+ assert result["success"] is False
312
+ # Error should mention the available epics
313
+ error_text = result["error"]
314
+ assert "76" in error_text or "77" in error_text
315
+
316
+ def test_epic_id_format_plain_number(self, sprint_file: Path) -> None:
317
+ """Should accept plain numeric epic ID like '76'."""
318
+ result = add_story(
319
+ sprint_path=sprint_file,
320
+ epic_id="76",
321
+ title="Test",
322
+ points=1,
323
+ )
324
+
325
+ assert result["success"] is True
326
+
327
+ def test_epic_id_format_with_prefix(self, sprint_file: Path) -> None:
328
+ """Should accept prefixed epic ID like 'epic-76'."""
329
+ result = add_story(
330
+ sprint_path=sprint_file,
331
+ epic_id="epic-76",
332
+ title="Test",
333
+ points=1,
334
+ )
335
+
336
+ assert result["success"] is True
337
+
338
+
339
+ # =============================================================================
340
+ # AC3: Field Population
341
+ # =============================================================================
342
+
343
+
344
+ class TestFieldPopulation:
345
+ """Populates required fields with defaults, optional fields only when provided."""
346
+
347
+ def test_required_fields_present(self, sprint_file: Path) -> None:
348
+ """Added story must have id, title, status, points."""
349
+ add_story(
350
+ sprint_path=sprint_file,
351
+ epic_id="76",
352
+ title="New feature",
353
+ points=3,
354
+ )
355
+
356
+ data = read_sprint(sprint_file)
357
+ epic = data["epics"][0]
358
+ new_story = epic["stories"][-1]
359
+
360
+ assert "id" in new_story
361
+ assert "title" in new_story
362
+ assert "status" in new_story
363
+ assert "points" in new_story
364
+
365
+ def test_default_status_is_backlog(self, sprint_file: Path) -> None:
366
+ """Default status should be 'backlog'."""
367
+ add_story(
368
+ sprint_path=sprint_file,
369
+ epic_id="76",
370
+ title="New feature",
371
+ points=3,
372
+ )
373
+
374
+ data = read_sprint(sprint_file)
375
+ new_story = data["epics"][0]["stories"][-1]
376
+
377
+ assert new_story["status"] == "backlog"
378
+
379
+ def test_default_priority_is_p1(self, sprint_file: Path) -> None:
380
+ """Default priority should be 'P1'."""
381
+ add_story(
382
+ sprint_path=sprint_file,
383
+ epic_id="76",
384
+ title="New feature",
385
+ points=3,
386
+ )
387
+
388
+ data = read_sprint(sprint_file)
389
+ new_story = data["epics"][0]["stories"][-1]
390
+
391
+ assert new_story["priority"] == "P1"
392
+
393
+ def test_default_workflow_is_tdd(self, sprint_file: Path) -> None:
394
+ """Default workflow should be 'tdd'."""
395
+ add_story(
396
+ sprint_path=sprint_file,
397
+ epic_id="76",
398
+ title="New feature",
399
+ points=3,
400
+ )
401
+
402
+ data = read_sprint(sprint_file)
403
+ new_story = data["epics"][0]["stories"][-1]
404
+
405
+ assert new_story["workflow"] == "tdd"
406
+
407
+ def test_title_preserved_exactly(self, sprint_file: Path) -> None:
408
+ """The title should be stored exactly as provided."""
409
+ add_story(
410
+ sprint_path=sprint_file,
411
+ epic_id="76",
412
+ title="Implement new feature: parsing",
413
+ points=5,
414
+ )
415
+
416
+ data = read_sprint(sprint_file)
417
+ new_story = data["epics"][0]["stories"][-1]
418
+
419
+ assert new_story["title"] == "Implement new feature: parsing"
420
+
421
+ def test_points_stored_as_integer(self, sprint_file: Path) -> None:
422
+ """Points should be stored as an integer."""
423
+ add_story(
424
+ sprint_path=sprint_file,
425
+ epic_id="76",
426
+ title="New feature",
427
+ points=5,
428
+ )
429
+
430
+ data = read_sprint(sprint_file)
431
+ new_story = data["epics"][0]["stories"][-1]
432
+
433
+ assert new_story["points"] == 5
434
+ assert isinstance(new_story["points"], int)
435
+
436
+ def test_optional_jira_included_when_provided(self, sprint_file: Path) -> None:
437
+ """Jira key should appear only when explicitly provided."""
438
+ add_story(
439
+ sprint_path=sprint_file,
440
+ epic_id="76",
441
+ title="New feature",
442
+ points=3,
443
+ jira="MSSCI-14999",
444
+ )
445
+
446
+ data = read_sprint(sprint_file)
447
+ new_story = data["epics"][0]["stories"][-1]
448
+
449
+ assert new_story["jira"] == "MSSCI-14999"
450
+
451
+ def test_optional_jira_absent_when_not_provided(self, sprint_file: Path) -> None:
452
+ """Jira key should NOT appear when not provided."""
453
+ add_story(
454
+ sprint_path=sprint_file,
455
+ epic_id="76",
456
+ title="New feature",
457
+ points=3,
458
+ )
459
+
460
+ data = read_sprint(sprint_file)
461
+ new_story = data["epics"][0]["stories"][-1]
462
+
463
+ assert "jira" not in new_story
464
+
465
+ def test_optional_type_included_when_provided(self, sprint_file: Path) -> None:
466
+ """Story type should appear only when explicitly provided."""
467
+ add_story(
468
+ sprint_path=sprint_file,
469
+ epic_id="76",
470
+ title="Fix bug",
471
+ points=2,
472
+ story_type="bug",
473
+ )
474
+
475
+ data = read_sprint(sprint_file)
476
+ new_story = data["epics"][0]["stories"][-1]
477
+
478
+ assert new_story.get("type") == "bug"
479
+
480
+ def test_custom_priority_overrides_default(self, sprint_file: Path) -> None:
481
+ """Custom priority should override the P1 default."""
482
+ add_story(
483
+ sprint_path=sprint_file,
484
+ epic_id="76",
485
+ title="Critical fix",
486
+ points=1,
487
+ priority="P0",
488
+ )
489
+
490
+ data = read_sprint(sprint_file)
491
+ new_story = data["epics"][0]["stories"][-1]
492
+
493
+ assert new_story["priority"] == "P0"
494
+
495
+ def test_custom_workflow_overrides_default(self, sprint_file: Path) -> None:
496
+ """Custom workflow should override the tdd default."""
497
+ add_story(
498
+ sprint_path=sprint_file,
499
+ epic_id="76",
500
+ title="Quick chore",
501
+ points=1,
502
+ workflow="trivial",
503
+ )
504
+
505
+ data = read_sprint(sprint_file)
506
+ new_story = data["epics"][0]["stories"][-1]
507
+
508
+ assert new_story["workflow"] == "trivial"
509
+
510
+
511
+ # =============================================================================
512
+ # AC4: Story Insertion and Key Ordering
513
+ # =============================================================================
514
+
515
+
516
+ class TestStoryPositioning:
517
+ """Story is appended at end of epic's stories list as CommentedMap."""
518
+
519
+ def test_appended_at_end(self, sprint_file: Path) -> None:
520
+ """New story should be the last story in the epic's list."""
521
+ add_story(
522
+ sprint_path=sprint_file,
523
+ epic_id="76",
524
+ title="New story",
525
+ points=3,
526
+ )
527
+
528
+ data = read_sprint(sprint_file)
529
+ stories = data["epics"][0]["stories"]
530
+
531
+ assert len(stories) == 3 # Was 2, now 3
532
+ assert stories[-1]["title"] == "New story"
533
+
534
+ def test_story_is_commented_map(self, sprint_file: Path) -> None:
535
+ """New story must be a CommentedMap, not a plain dict."""
536
+ add_story(
537
+ sprint_path=sprint_file,
538
+ epic_id="76",
539
+ title="New story",
540
+ points=3,
541
+ )
542
+
543
+ data = read_sprint(sprint_file)
544
+ new_story = data["epics"][0]["stories"][-1]
545
+
546
+ assert isinstance(new_story, CommentedMap)
547
+
548
+ def test_key_ordering_follows_story_key_order(self, sprint_file: Path) -> None:
549
+ """Keys in the new story should follow STORY_KEY_ORDER."""
550
+ add_story(
551
+ sprint_path=sprint_file,
552
+ epic_id="76",
553
+ title="New story",
554
+ points=3,
555
+ )
556
+
557
+ data = read_sprint(sprint_file)
558
+ new_story = data["epics"][0]["stories"][-1]
559
+
560
+ actual_keys = list(new_story.keys())
561
+ expected_order = [k for k in STORY_KEY_ORDER if k in actual_keys]
562
+
563
+ assert actual_keys == expected_order
564
+
565
+ def test_existing_stories_unchanged(self, sprint_file: Path) -> None:
566
+ """Existing stories should not be modified by the add."""
567
+ data_before = read_sprint(sprint_file)
568
+ original_first = dict(data_before["epics"][0]["stories"][0])
569
+
570
+ add_story(
571
+ sprint_path=sprint_file,
572
+ epic_id="76",
573
+ title="New story",
574
+ points=3,
575
+ )
576
+
577
+ data_after = read_sprint(sprint_file)
578
+ first_after = data_after["epics"][0]["stories"][0]
579
+
580
+ assert first_after["id"] == original_first["id"]
581
+ assert first_after["title"] == original_first["title"]
582
+ assert first_after["points"] == original_first["points"]
583
+
584
+ def test_add_to_second_epic(self, multi_epic_file: Path) -> None:
585
+ """Should be able to add a story to a non-first epic."""
586
+ add_story(
587
+ sprint_path=multi_epic_file,
588
+ epic_id="77",
589
+ title="New story in epic 77",
590
+ points=2,
591
+ )
592
+
593
+ data = read_sprint(multi_epic_file)
594
+ epic_77 = data["epics"][1]
595
+
596
+ assert len(epic_77["stories"]) == 2
597
+ assert epic_77["stories"][-1]["title"] == "New story in epic 77"
598
+ assert epic_77["stories"][-1]["id"] == "77-2"
599
+
600
+
601
+ # =============================================================================
602
+ # AC5: File Validation After Insertion
603
+ # =============================================================================
604
+
605
+
606
+ class TestFileValidation:
607
+ """Validates entire sprint file after insertion, aborts on failure."""
608
+
609
+ def test_file_valid_after_insertion(self, sprint_file: Path) -> None:
610
+ """Sprint file should pass validation after a successful add."""
611
+ from pennyfarthing_scripts.sprint.validator import validate_full_sprint
612
+
613
+ add_story(
614
+ sprint_path=sprint_file,
615
+ epic_id="76",
616
+ title="New story",
617
+ points=3,
618
+ )
619
+
620
+ data = read_sprint(sprint_file)
621
+ result = validate_full_sprint(data)
622
+
623
+ assert result.valid
624
+
625
+ def test_atomic_write_on_success(self, sprint_file: Path) -> None:
626
+ """Successful add should produce a valid YAML file on disk."""
627
+ add_story(
628
+ sprint_path=sprint_file,
629
+ epic_id="76",
630
+ title="New story",
631
+ points=3,
632
+ )
633
+
634
+ # File should be readable and valid
635
+ data = read_sprint(sprint_file)
636
+ assert data is not None
637
+ assert len(data["epics"][0]["stories"]) == 3
638
+
639
+ def test_no_temp_files_after_success(self, sprint_file: Path) -> None:
640
+ """No .yaml.tmp file should remain after successful add."""
641
+ add_story(
642
+ sprint_path=sprint_file,
643
+ epic_id="76",
644
+ title="New story",
645
+ points=3,
646
+ )
647
+
648
+ tmp_file = sprint_file.with_suffix(".yaml.tmp")
649
+ assert not tmp_file.exists()
650
+
651
+ def test_original_preserved_on_validation_failure(self, tmp_path: Path) -> None:
652
+ """If post-insertion validation fails, original file should be untouched."""
653
+ # Create a file with a story that would cause duplicate ID
654
+ yaml_content = """\
655
+ sprint:
656
+ name: "TO Sprint 2604"
657
+ jira_sprint_id: 276
658
+ jira_sprint_name: "TO Sprint 2604"
659
+ goal: Complete the sprint
660
+ start_date: 2026-01-20
661
+ end_date: 2026-02-02
662
+ status: active
663
+ number: 2604
664
+ epics:
665
+ - id: epic-99
666
+ type: epic
667
+ title: "Epic: Test"
668
+ priority: P1
669
+ status: in_progress
670
+ jira: MSSCI-99999
671
+ stories:
672
+ - id: 99-1
673
+ title: Existing
674
+ points: 1
675
+ status: backlog
676
+ """
677
+ p = tmp_path / "current-sprint.yaml"
678
+ p.write_text(yaml_content)
679
+ original_content = p.read_text()
680
+
681
+ # Normal add should work fine
682
+ result = add_story(
683
+ sprint_path=p,
684
+ epic_id="99",
685
+ title="Second story",
686
+ points=2,
687
+ )
688
+
689
+ assert result["success"] is True
690
+
691
+
692
+ # =============================================================================
693
+ # AC6: CLI Interface
694
+ # =============================================================================
695
+
696
+
697
+ class TestCLIIntegration:
698
+ """CLI: /sprint story add <epic_id> <title> <points> with options."""
699
+
700
+ def test_story_add_command_exists(self) -> None:
701
+ """story_add_command should be importable and be a Click command."""
702
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
703
+
704
+ import click
705
+
706
+ assert isinstance(story_add_command, click.BaseCommand)
707
+
708
+ def test_basic_add_via_cli(self, runner: CliRunner, sprint_file: Path) -> None:
709
+ """Basic CLI invocation should add a story successfully."""
710
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
711
+
712
+ result = runner.invoke(story_add_command, [
713
+ "--sprint-file", str(sprint_file),
714
+ "76", "New CLI story", "3",
715
+ ])
716
+
717
+ assert result.exit_code == 0
718
+
719
+ def test_cli_with_jira_option(self, runner: CliRunner, sprint_file: Path) -> None:
720
+ """--jira option should set the jira field."""
721
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
722
+
723
+ result = runner.invoke(story_add_command, [
724
+ "--sprint-file", str(sprint_file),
725
+ "76", "Jira story", "3",
726
+ "--jira", "MSSCI-14999",
727
+ ])
728
+
729
+ assert result.exit_code == 0
730
+
731
+ data = read_sprint(sprint_file)
732
+ new_story = data["epics"][0]["stories"][-1]
733
+ assert new_story["jira"] == "MSSCI-14999"
734
+
735
+ def test_cli_with_type_option(self, runner: CliRunner, sprint_file: Path) -> None:
736
+ """--type option should set the story type."""
737
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
738
+
739
+ result = runner.invoke(story_add_command, [
740
+ "--sprint-file", str(sprint_file),
741
+ "76", "Bug fix", "2",
742
+ "--type", "bug",
743
+ ])
744
+
745
+ assert result.exit_code == 0
746
+
747
+ def test_cli_with_priority_option(self, runner: CliRunner, sprint_file: Path) -> None:
748
+ """--priority option should override default P1."""
749
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
750
+
751
+ result = runner.invoke(story_add_command, [
752
+ "--sprint-file", str(sprint_file),
753
+ "76", "Critical", "1",
754
+ "--priority", "P0",
755
+ ])
756
+
757
+ assert result.exit_code == 0
758
+
759
+ data = read_sprint(sprint_file)
760
+ new_story = data["epics"][0]["stories"][-1]
761
+ assert new_story["priority"] == "P0"
762
+
763
+ def test_cli_with_workflow_option(self, runner: CliRunner, sprint_file: Path) -> None:
764
+ """--workflow option should override default tdd."""
765
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
766
+
767
+ result = runner.invoke(story_add_command, [
768
+ "--sprint-file", str(sprint_file),
769
+ "76", "Quick task", "1",
770
+ "--workflow", "trivial",
771
+ ])
772
+
773
+ assert result.exit_code == 0
774
+
775
+ data = read_sprint(sprint_file)
776
+ new_story = data["epics"][0]["stories"][-1]
777
+ assert new_story["workflow"] == "trivial"
778
+
779
+ def test_cli_nonexistent_epic_exits_nonzero(
780
+ self, runner: CliRunner, sprint_file: Path
781
+ ) -> None:
782
+ """Specifying a non-existent epic should produce non-zero exit code."""
783
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
784
+
785
+ result = runner.invoke(story_add_command, [
786
+ "--sprint-file", str(sprint_file),
787
+ "999", "Phantom story", "3",
788
+ ])
789
+
790
+ assert result.exit_code != 0
791
+
792
+ def test_cli_success_output(self, runner: CliRunner, sprint_file: Path) -> None:
793
+ """Successful add should show the new story ID."""
794
+ from pennyfarthing_scripts.sprint.story_add import story_add_command
795
+
796
+ result = runner.invoke(story_add_command, [
797
+ "--sprint-file", str(sprint_file),
798
+ "76", "New story", "3",
799
+ ])
800
+
801
+ assert result.exit_code == 0
802
+ assert "76-3" in result.output
803
+
804
+
805
+ # =============================================================================
806
+ # AC7: Edge Cases
807
+ # =============================================================================
808
+
809
+
810
+ class TestEdgeCases:
811
+ """Handles YAML-special chars, first story in new epic, sequence gaps."""
812
+
813
+ def test_title_with_colon(self, sprint_file: Path) -> None:
814
+ """Title containing colons should be handled correctly."""
815
+ add_story(
816
+ sprint_path=sprint_file,
817
+ epic_id="76",
818
+ title="Feature: implement parsing",
819
+ points=3,
820
+ )
821
+
822
+ data = read_sprint(sprint_file)
823
+ new_story = data["epics"][0]["stories"][-1]
824
+
825
+ assert new_story["title"] == "Feature: implement parsing"
826
+
827
+ def test_title_with_quotes(self, sprint_file: Path) -> None:
828
+ """Title containing quotes should be handled correctly."""
829
+ add_story(
830
+ sprint_path=sprint_file,
831
+ epic_id="76",
832
+ title='Fix "broken" feature',
833
+ points=2,
834
+ )
835
+
836
+ data = read_sprint(sprint_file)
837
+ new_story = data["epics"][0]["stories"][-1]
838
+
839
+ assert new_story["title"] == 'Fix "broken" feature'
840
+
841
+ def test_title_with_yaml_special_chars(self, sprint_file: Path) -> None:
842
+ """Title with brackets, ampersands, etc. should survive round-trip."""
843
+ add_story(
844
+ sprint_path=sprint_file,
845
+ epic_id="76",
846
+ title="Handle [special] {chars} & *asterisks*",
847
+ points=2,
848
+ )
849
+
850
+ data = read_sprint(sprint_file)
851
+ new_story = data["epics"][0]["stories"][-1]
852
+
853
+ assert new_story["title"] == "Handle [special] {chars} & *asterisks*"
854
+
855
+ def test_first_story_in_empty_epic(self, empty_stories_file: Path) -> None:
856
+ """Adding the first story to an epic with empty stories list."""
857
+ result = add_story(
858
+ sprint_path=empty_stories_file,
859
+ epic_id="80",
860
+ title="First story ever",
861
+ points=3,
862
+ )
863
+
864
+ assert result["success"] is True
865
+
866
+ data = read_sprint(empty_stories_file)
867
+ epic = data["epics"][0]
868
+
869
+ assert len(epic["stories"]) == 1
870
+ assert epic["stories"][0]["id"] == "80-1"
871
+ assert epic["stories"][0]["title"] == "First story ever"
872
+
873
+ def test_gapped_ids_uses_max_plus_one(self, gapped_ids_file: Path) -> None:
874
+ """With gaps in IDs (50-1, 50-3, 50-5), next should be 50-6."""
875
+ result = add_story(
876
+ sprint_path=gapped_ids_file,
877
+ epic_id="50",
878
+ title="After the gaps",
879
+ points=2,
880
+ )
881
+
882
+ assert result["success"] is True
883
+
884
+ data = read_sprint(gapped_ids_file)
885
+ new_story = data["epics"][0]["stories"][-1]
886
+
887
+ assert new_story["id"] == "50-6"
888
+
889
+ def test_multiple_adds_sequential(self, sprint_file: Path) -> None:
890
+ """Adding two stories in sequence should give sequential IDs."""
891
+ add_story(
892
+ sprint_path=sprint_file,
893
+ epic_id="76",
894
+ title="Third story",
895
+ points=2,
896
+ )
897
+ add_story(
898
+ sprint_path=sprint_file,
899
+ epic_id="76",
900
+ title="Fourth story",
901
+ points=1,
902
+ )
903
+
904
+ data = read_sprint(sprint_file)
905
+ stories = data["epics"][0]["stories"]
906
+
907
+ assert len(stories) == 4
908
+ assert stories[-2]["id"] == "76-3"
909
+ assert stories[-1]["id"] == "76-4"
910
+
911
+ def test_result_includes_story_id(self, sprint_file: Path) -> None:
912
+ """Successful result should include the generated story ID."""
913
+ result = add_story(
914
+ sprint_path=sprint_file,
915
+ epic_id="76",
916
+ title="New story",
917
+ points=3,
918
+ )
919
+
920
+ assert result["success"] is True
921
+ assert result["story_id"] == "76-3"