@pennyfarthing/core 10.0.2 → 10.0.5
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.
- package/README.md +287 -0
- package/package.json +29 -41
- package/{dist → packages/core/dist}/cli/commands/cyclist.d.ts +5 -1
- package/packages/core/dist/cli/commands/cyclist.d.ts.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/cyclist.js +4 -4
- package/packages/core/dist/cli/commands/cyclist.js.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/cyclist.test.js +2 -2
- package/packages/core/dist/cli/commands/cyclist.test.js.map +1 -0
- package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts +13 -0
- package/packages/core/dist/cli/commands/doctor-file-layout.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/doctor-file-layout.test.js +234 -0
- package/packages/core/dist/cli/commands/doctor-file-layout.test.js.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js +17 -16
- package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.js.map +1 -1
- package/{dist → packages/core/dist}/cli/commands/doctor.d.ts +8 -0
- package/{dist → packages/core/dist}/cli/commands/doctor.d.ts.map +1 -1
- package/{dist → packages/core/dist}/cli/commands/doctor.js +224 -3
- package/packages/core/dist/cli/commands/doctor.js.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.js +1 -1
- package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.js.map +1 -1
- package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.js +1 -1
- package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.js.map +1 -1
- package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts +19 -0
- package/packages/core/dist/cli/commands/hooks-consolidation.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/hooks-consolidation.test.js +358 -0
- package/packages/core/dist/cli/commands/hooks-consolidation.test.js.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/init.d.ts.map +1 -1
- package/{dist → packages/core/dist}/cli/commands/init.js +3 -0
- package/packages/core/dist/cli/commands/init.js.map +1 -0
- package/{dist → packages/core/dist}/cli/commands/update.d.ts.map +1 -1
- package/{dist → packages/core/dist}/cli/commands/update.js +53 -1
- package/{dist → packages/core/dist}/cli/commands/update.js.map +1 -1
- package/{dist → packages/core/dist}/cli/ocean-profiles.test.js +1 -1
- package/{dist → packages/core/dist}/cli/ocean-profiles.test.js.map +1 -1
- package/{dist → packages/core/dist}/cli/utils/files.d.ts +10 -0
- package/{dist → packages/core/dist}/cli/utils/files.d.ts.map +1 -1
- package/{dist → packages/core/dist}/cli/utils/files.js +35 -0
- package/{dist → packages/core/dist}/cli/utils/files.js.map +1 -1
- package/{dist → packages/core/dist}/cli/utils/settings.d.ts.map +1 -1
- package/{dist → packages/core/dist}/cli/utils/settings.js +24 -0
- package/packages/core/dist/cli/utils/settings.js.map +1 -0
- package/{dist → packages/core/dist}/cli/utils/themes.d.ts +1 -0
- package/packages/core/dist/cli/utils/themes.d.ts.map +1 -0
- package/{dist → packages/core/dist}/cli/utils/themes.js.map +1 -1
- package/{dist → packages/core/dist}/scripts/generate-report.d.ts.map +1 -1
- package/{dist → packages/core/dist}/scripts/generate-report.js +11 -7
- package/packages/core/dist/scripts/generate-report.js.map +1 -0
- package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts.map +1 -1
- package/{dist → packages/core/dist}/scripts/generate-spider-report.js +12 -8
- package/packages/core/dist/scripts/generate-spider-report.js.map +1 -0
- package/packages/core/dist/scripts/generate-spider.d.ts.map +1 -0
- package/{dist → packages/core/dist}/scripts/generate-spider.js +6 -4
- package/packages/core/dist/scripts/generate-spider.js.map +1 -0
- package/{dist → packages/core/dist}/scripts/generate-spider.test.js +2 -2
- package/packages/core/dist/scripts/generate-spider.test.js.map +1 -0
- package/pennyfarthing-dist/agents/pm.md +1 -1
- package/pennyfarthing-dist/agents/sm-finish.md +1 -1
- package/pennyfarthing-dist/agents/sm-setup.md +6 -6
- package/pennyfarthing-dist/agents/sm.md +12 -6
- package/pennyfarthing-dist/agents/workflow-status-check.md +1 -1
- package/pennyfarthing-dist/commands/repo-status.md +2 -2
- package/pennyfarthing-dist/commands/sprint.md +8 -8
- package/pennyfarthing-dist/guides/bell-mode.md +65 -0
- package/pennyfarthing-dist/guides/benchmarks.md +62 -0
- package/pennyfarthing-dist/guides/bikelane.md +86 -0
- package/pennyfarthing-dist/guides/prime.md +72 -0
- package/pennyfarthing-dist/guides/reflector.md +59 -0
- package/pennyfarthing-dist/guides/relay-mode.md +53 -0
- package/pennyfarthing-dist/guides/skill-schema.md +25 -26
- package/pennyfarthing-dist/guides/tirepump.md +54 -0
- package/pennyfarthing-dist/guides/xml-tags.md +2 -2
- package/pennyfarthing-dist/personas/themes/battlestar-galactica.yaml +59 -58
- package/pennyfarthing-dist/personas/themes/blade-runner.yaml +10 -10
- package/pennyfarthing-dist/personas/themes/doctor-who.yaml +10 -10
- package/pennyfarthing-dist/personas/themes/dune.yaml +64 -69
- package/pennyfarthing-dist/personas/themes/firefly.yaml +60 -73
- package/pennyfarthing-dist/personas/themes/game-of-thrones.yaml +60 -69
- package/pennyfarthing-dist/personas/themes/harry-potter.yaml +59 -73
- package/pennyfarthing-dist/personas/themes/hitchhikers-guide.yaml +45 -57
- package/pennyfarthing-dist/personas/themes/mad-max.yaml +5 -11
- package/pennyfarthing-dist/personas/themes/princess-bride.yaml +53 -63
- package/pennyfarthing-dist/personas/themes/sandman.yaml +59 -59
- package/pennyfarthing-dist/personas/themes/the-matrix.yaml +61 -62
- package/pennyfarthing-dist/personas/themes/west-wing.yaml +8 -9
- package/pennyfarthing-dist/scripts/README.md +2 -2
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +1 -1
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +3 -3
- package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +32 -0
- package/pennyfarthing-dist/scripts/hooks/post-merge.sh +2 -7
- package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +1 -1
- package/pennyfarthing-dist/scripts/jira/create-jira-epic.sh +12 -91
- package/pennyfarthing-dist/scripts/jira/create-jira-story.sh +11 -86
- package/pennyfarthing-dist/scripts/jira/jira-reconcile.sh +11 -255
- package/pennyfarthing-dist/scripts/misc/repo-utils.sh +3 -3
- package/pennyfarthing-dist/scripts/sprint/README.md +32 -17
- package/pennyfarthing-dist/scripts/story/README.md +1 -1
- package/pennyfarthing-dist/scripts/test/test-setup.sh +1 -1
- package/pennyfarthing-dist/skills/jira/SKILL.md +107 -408
- package/pennyfarthing-dist/skills/skill-registry.yaml +21 -12
- package/pennyfarthing-dist/skills/sprint/skill.md +386 -68
- package/pennyfarthing-dist/skills/story/skill.md +14 -206
- package/pennyfarthing-dist/templates/settings.local.json.template +9 -1
- package/pennyfarthing-dist/workflows/epics-and-stories/steps/step-05-import-to-future.md +1 -1
- package/pennyfarthing-dist/workflows/git-cleanup.yaml +1 -1
- package/pennyfarthing-dist/workflows/project-setup/steps/step-10-complete.md +1 -1
- package/pennyfarthing_scripts/README.md +66 -0
- package/pennyfarthing_scripts/__init__.py +17 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bellmode_hook.py +154 -0
- package/pennyfarthing_scripts/brownfield/__init__.py +35 -0
- package/pennyfarthing_scripts/brownfield/__main__.py +7 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/cli.py +131 -0
- package/pennyfarthing_scripts/brownfield/discover.py +753 -0
- package/pennyfarthing_scripts/cli.py +184 -0
- package/pennyfarthing_scripts/common/__init__.py +49 -0
- package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/config.py +92 -0
- package/pennyfarthing_scripts/common/output.py +180 -0
- package/pennyfarthing_scripts/common/themes.py +253 -0
- package/pennyfarthing_scripts/config.py +21 -0
- package/pennyfarthing_scripts/context.py +414 -0
- package/pennyfarthing_scripts/git/__init__.py +29 -0
- package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/create_branches.py +439 -0
- package/pennyfarthing_scripts/git/status_all.py +310 -0
- package/pennyfarthing_scripts/hooks/cyclist-pretooluse-hook.sh +7 -0
- package/pennyfarthing_scripts/hooks.py +454 -0
- package/pennyfarthing_scripts/hotspots/__init__.py +31 -0
- package/pennyfarthing_scripts/hotspots/__main__.py +6 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/analyze.py +472 -0
- package/pennyfarthing_scripts/hotspots/cli.py +152 -0
- package/pennyfarthing_scripts/hotspots/formatters.py +109 -0
- package/pennyfarthing_scripts/hotspots/models.py +60 -0
- package/pennyfarthing_scripts/jira/__init__.py +99 -0
- package/pennyfarthing_scripts/jira/__main__.py +10 -0
- package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/bidirectional.py +561 -0
- package/pennyfarthing_scripts/jira/claim.py +211 -0
- package/pennyfarthing_scripts/jira/cli.py +351 -0
- package/pennyfarthing_scripts/jira/client.py +762 -0
- package/pennyfarthing_scripts/jira/create.py +267 -0
- package/pennyfarthing_scripts/jira/epic.py +176 -0
- package/pennyfarthing_scripts/jira/operations.py +124 -0
- package/pennyfarthing_scripts/jira/reconcile.py +277 -0
- package/pennyfarthing_scripts/jira/story.py +219 -0
- package/pennyfarthing_scripts/jira/sync.py +350 -0
- package/pennyfarthing_scripts/jira_bidirectional_sync.py +37 -0
- package/pennyfarthing_scripts/jira_epic_creation.py +30 -0
- package/pennyfarthing_scripts/jira_sync.py +36 -0
- package/pennyfarthing_scripts/jira_sync_story.py +30 -0
- package/pennyfarthing_scripts/migration/__init__.py +39 -0
- package/pennyfarthing_scripts/migration/__main__.py +10 -0
- package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/cli.py +304 -0
- package/pennyfarthing_scripts/migration/session.py +384 -0
- package/pennyfarthing_scripts/migration/skill.py +188 -0
- package/pennyfarthing_scripts/migration/step.py +229 -0
- package/pennyfarthing_scripts/migration/validate.py +282 -0
- package/pennyfarthing_scripts/output.py +37 -0
- package/pennyfarthing_scripts/patch_mode.py +449 -0
- package/pennyfarthing_scripts/preflight/__init__.py +17 -0
- package/pennyfarthing_scripts/preflight/__main__.py +10 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/cli.py +141 -0
- package/pennyfarthing_scripts/preflight/finish.py +382 -0
- package/pennyfarthing_scripts/pretooluse_hook.py +193 -0
- package/pennyfarthing_scripts/prime/__init__.py +125 -0
- package/pennyfarthing_scripts/prime/__main__.py +8 -0
- package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/cli.py +645 -0
- package/pennyfarthing_scripts/prime/loader.py +239 -0
- package/pennyfarthing_scripts/prime/models.py +206 -0
- package/pennyfarthing_scripts/prime/persona.py +309 -0
- package/pennyfarthing_scripts/prime/session.py +183 -0
- package/pennyfarthing_scripts/prime/tiers.py +201 -0
- package/pennyfarthing_scripts/prime/workflow.py +277 -0
- package/pennyfarthing_scripts/schema_validation_hook.py +306 -0
- package/pennyfarthing_scripts/sprint/__init__.py +66 -0
- package/pennyfarthing_scripts/sprint/__main__.py +10 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/archive.py +165 -0
- package/pennyfarthing_scripts/sprint/archive_epic.py +408 -0
- package/pennyfarthing_scripts/sprint/cli.py +1863 -0
- package/pennyfarthing_scripts/sprint/epic_add.py +173 -0
- package/pennyfarthing_scripts/sprint/import_epic.py +431 -0
- package/pennyfarthing_scripts/sprint/loader.py +237 -0
- package/pennyfarthing_scripts/sprint/status.py +122 -0
- package/pennyfarthing_scripts/sprint/story_add.py +187 -0
- package/pennyfarthing_scripts/sprint/story_update.py +181 -0
- package/pennyfarthing_scripts/sprint/validate_cmd.py +307 -0
- package/pennyfarthing_scripts/sprint/validator.py +580 -0
- package/pennyfarthing_scripts/sprint/work.py +208 -0
- package/pennyfarthing_scripts/sprint/yaml_io.py +367 -0
- package/pennyfarthing_scripts/story/__init__.py +67 -0
- package/pennyfarthing_scripts/story/__main__.py +10 -0
- package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/cli.py +105 -0
- package/pennyfarthing_scripts/story/create.py +167 -0
- package/pennyfarthing_scripts/story/size.py +113 -0
- package/pennyfarthing_scripts/story/template.py +151 -0
- package/pennyfarthing_scripts/swebench.py +216 -0
- package/pennyfarthing_scripts/tests/__init__.py +1 -0
- package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/conftest.py +106 -0
- package/pennyfarthing_scripts/tests/test_brownfield.py +842 -0
- package/pennyfarthing_scripts/tests/test_cli_modules.py +245 -0
- package/pennyfarthing_scripts/tests/test_common.py +180 -0
- package/pennyfarthing_scripts/tests/test_git_utils.py +866 -0
- package/pennyfarthing_scripts/tests/test_jira_package.py +334 -0
- package/pennyfarthing_scripts/tests/test_package_structure.py +372 -0
- package/pennyfarthing_scripts/tests/test_patch_mode.py +830 -0
- package/pennyfarthing_scripts/tests/test_prime.py +1050 -0
- package/pennyfarthing_scripts/tests/test_sprint_package.py +402 -0
- package/pennyfarthing_scripts/tests/test_sprint_validator.py +731 -0
- package/pennyfarthing_scripts/tests/test_story_add.py +921 -0
- package/pennyfarthing_scripts/tests/test_story_package.py +156 -0
- package/pennyfarthing_scripts/tests/test_story_update.py +769 -0
- package/pennyfarthing_scripts/tests/test_tiers.py +1090 -0
- package/pennyfarthing_scripts/tests/test_token_counting.py +559 -0
- package/pennyfarthing_scripts/tests/test_validate_cmd.py +500 -0
- package/pennyfarthing_scripts/tests/test_workflow_check.py +341 -0
- package/pennyfarthing_scripts/tests/test_yaml_io.py +815 -0
- package/pennyfarthing_scripts/welcome_hook.py +157 -0
- package/pennyfarthing_scripts/workflow.py +287 -0
- package/scripts/postinstall.cjs +34 -0
- package/dist/cli/commands/cyclist.d.ts.map +0 -1
- package/dist/cli/commands/cyclist.js.map +0 -1
- package/dist/cli/commands/cyclist.test.js.map +0 -1
- package/dist/cli/commands/doctor.js.map +0 -1
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/utils/settings.js.map +0 -1
- package/dist/cli/utils/themes.d.ts.map +0 -1
- package/dist/scripts/generate-report.js.map +0 -1
- package/dist/scripts/generate-spider-report.js.map +0 -1
- package/dist/scripts/generate-spider.d.ts.map +0 -1
- package/dist/scripts/generate-spider.js.map +0 -1
- package/dist/scripts/generate-spider.test.js.map +0 -1
- package/pennyfarthing-dist/scripts/jira/jira-lib.sh +0 -464
- package/pennyfarthing-dist/scripts/jira/jira-sync.sh +0 -16
- package/pennyfarthing-dist/scripts/jira/sync-epic-to-jira.sh +0 -16
- package/pennyfarthing-dist/scripts/sprint/archive-story.sh +0 -133
- package/pennyfarthing-dist/scripts/sprint/available-stories.sh +0 -91
- package/pennyfarthing-dist/scripts/sprint/check-story.sh +0 -158
- package/pennyfarthing-dist/scripts/sprint/get-epic-field.sh +0 -52
- package/pennyfarthing-dist/scripts/sprint/get-story-field.sh +0 -63
- package/pennyfarthing-dist/scripts/sprint/list-future.sh +0 -145
- package/pennyfarthing-dist/scripts/sprint/new-sprint.sh +0 -110
- package/pennyfarthing-dist/scripts/sprint/promote-epic.sh +0 -148
- package/pennyfarthing-dist/scripts/sprint/sprint-common.sh +0 -415
- package/pennyfarthing-dist/scripts/sprint/sprint-info.sh +0 -33
- package/pennyfarthing-dist/scripts/sprint/sprint-metrics.sh +0 -230
- package/pennyfarthing-dist/scripts/sprint/sprint-status.sh +0 -134
- package/pennyfarthing-dist/scripts/sprint/validate-sprint-yaml.sh +0 -139
- package/pennyfarthing-dist/skills/sprint/scripts/archive-story.sh +0 -101
- package/pennyfarthing-dist/skills/sprint/scripts/available-stories.sh +0 -97
- package/pennyfarthing-dist/skills/sprint/scripts/check-story.sh +0 -164
- package/pennyfarthing-dist/skills/sprint/scripts/create-jira-epic.sh +0 -101
- package/pennyfarthing-dist/skills/sprint/scripts/new-sprint.sh +0 -116
- package/pennyfarthing-dist/skills/sprint/scripts/promote-epic.sh +0 -164
- package/pennyfarthing-dist/skills/sprint/scripts/sprint-info.sh +0 -39
- package/pennyfarthing-dist/skills/sprint/scripts/sprint-status.sh +0 -147
- package/pennyfarthing-dist/skills/sprint/scripts/sync-epic-jira.sh +0 -93
- /package/{bin → packages/core/bin}/pennyfarthing.js +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.js +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.test.js +0 -0
- /package/{dist → packages/core/dist}/bmad/context-reader.test.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.js +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.test.js +0 -0
- /package/{dist → packages/core/dist}/bmad/epics-parser.test.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/index.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/index.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/index.js +0 -0
- /package/{dist → packages/core/dist}/bmad/index.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.js +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.test.js +0 -0
- /package/{dist → packages/core/dist}/bmad/status-sync.test.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.js +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.test.js +0 -0
- /package/{dist → packages/core/dist}/bmad/story-exporter.test.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.js +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.js.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.test.js +0 -0
- /package/{dist → packages/core/dist}/bmad/story-parser.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/command.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/command.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/command.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/command.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/cyclist.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/doctor-legacy.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/e2e-fresh-install.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/e2e-upgrade.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/init-consolidation.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/init.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/persona-config-consolidation.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/skill.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/skill.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/skill.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/skill.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/theme.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/theme.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/theme.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/theme.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/uninstall.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/uninstall.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/uninstall.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/update-consolidation.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/update.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/version.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/commands/version.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/commands/version.js +0 -0
- /package/{dist → packages/core/dist}/cli/commands/version.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/customization.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/customization.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/customization.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/customization.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/cyclist-migration.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/cyclist-migration.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/index.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/index.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/index.js +0 -0
- /package/{dist → packages/core/dist}/cli/index.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/ocean-profiles.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/theme-maker.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/theme-maker.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/theme-maker.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/constants.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/constants.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/constants.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/constants.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/logger.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/logger.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/logger.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/logger.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/manifest.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/manifest.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/manifest.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/node-modules.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/node-modules.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/node-modules.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/prompts.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/prompts.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/prompts.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/settings-consolidation.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/settings.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/symlinks.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/symlinks.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/symlinks.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/themes.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/themes.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/themes.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/themes.test.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/version.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/utils/version.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/utils/version.js +0 -0
- /package/{dist → packages/core/dist}/cli/utils/version.js.map +0 -0
- /package/{dist → packages/core/dist}/cli/workspace.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/cli/workspace.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/cli/workspace.test.js +0 -0
- /package/{dist → packages/core/dist}/cli/workspace.test.js.map +0 -0
- /package/{dist → packages/core/dist}/index.d.ts +0 -0
- /package/{dist → packages/core/dist}/index.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/index.js +0 -0
- /package/{dist → packages/core/dist}/index.js.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.js +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.js.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js +0 -0
- /package/{dist → packages/core/dist}/jira/jira-epic-creation.test.js.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.js.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js +0 -0
- /package/{dist → packages/core/dist}/jira/jira-sprint-sync.test.js.map +0 -0
- /package/{dist → packages/core/dist}/permissions/index.d.ts +0 -0
- /package/{dist → packages/core/dist}/permissions/index.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/permissions/index.js +0 -0
- /package/{dist → packages/core/dist}/permissions/index.js.map +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.js +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.js.map +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.test.js +0 -0
- /package/{dist → packages/core/dist}/permissions/permission-schema.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js +0 -0
- /package/{dist → packages/core/dist}/scripts/add-ocean-profiles.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.js +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/benchmark-integration.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/debugging-scenarios.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-all-spiders.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-all-spiders.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-report.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-report.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-report.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-report.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider-report.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider-report.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/generate-spider.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/job-fair-aggregator.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/run-ci.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/run-ci.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/run-ci.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/theme-detail.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/theme-detail.test.js +0 -0
- /package/{dist → packages/core/dist}/scripts/theme-detail.test.js.map +0 -0
- /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts +0 -0
- /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js +0 -0
- /package/{dist → packages/core/dist}/scripts/validate-ocean-profiles.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/complete-step-integration.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.js +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/gate-handler.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-finish.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-finish.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-setup.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js +0 -0
- /package/{dist → packages/core/dist}/workflow/generic-sm-setup.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.js +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/handoff.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/index.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/index.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/index.js +0 -0
- /package/{dist → packages/core/dist}/workflow/index.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.js +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/session-state.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/sm-subagents.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/sm-subagents.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.js +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/step-parser.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/story-workflow-routing.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.js +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/test-cache.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.js +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/trimodal.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.js +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/variable-resolver.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-executor.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-loader.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-migration.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-migration.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-permissions.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-router.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-schema.test.js.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.d.ts.map +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js +0 -0
- /package/{dist → packages/core/dist}/workflow/workflow-stepped-schema.test.js.map +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sprint work session management.
|
|
3
|
+
|
|
4
|
+
Provides functions for starting and managing work on stories.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from pennyfarthing_scripts.sprint.loader import (
|
|
10
|
+
find_epic,
|
|
11
|
+
find_story,
|
|
12
|
+
get_stories_by_status,
|
|
13
|
+
get_story_by_id,
|
|
14
|
+
load_sprint,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def check_story(story_id: str) -> dict[str, Any]:
|
|
19
|
+
"""Check if a story is available for work.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
story_id: Story ID or Jira key
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Dict with availability status and story details
|
|
26
|
+
"""
|
|
27
|
+
story = get_story_by_id(story_id)
|
|
28
|
+
|
|
29
|
+
if not story:
|
|
30
|
+
return {
|
|
31
|
+
"available": False,
|
|
32
|
+
"error": f"Story '{story_id}' not found",
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
status = story.get("status", "backlog")
|
|
36
|
+
assigned = story.get("assigned_to")
|
|
37
|
+
|
|
38
|
+
# Check if already in progress
|
|
39
|
+
if status == "in_progress":
|
|
40
|
+
return {
|
|
41
|
+
"available": False,
|
|
42
|
+
"type": "story",
|
|
43
|
+
"story": story,
|
|
44
|
+
"reason": "Already in progress",
|
|
45
|
+
"assigned_to": assigned,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Check if done
|
|
49
|
+
if status in ("done", "completed"):
|
|
50
|
+
return {
|
|
51
|
+
"available": False,
|
|
52
|
+
"type": "story",
|
|
53
|
+
"story": story,
|
|
54
|
+
"reason": "Already completed",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Check if canceled
|
|
58
|
+
if status == "canceled":
|
|
59
|
+
return {
|
|
60
|
+
"available": False,
|
|
61
|
+
"type": "story",
|
|
62
|
+
"story": story,
|
|
63
|
+
"reason": "Story is canceled",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Available statuses: backlog, ready, planning
|
|
67
|
+
return {
|
|
68
|
+
"available": True,
|
|
69
|
+
"type": "story",
|
|
70
|
+
"story": story,
|
|
71
|
+
"title": story.get("title"),
|
|
72
|
+
"points": story.get("points"),
|
|
73
|
+
"workflow": story.get("workflow", "tdd"),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_next_story() -> dict[str, Any]:
|
|
78
|
+
"""Get the highest priority available story.
|
|
79
|
+
|
|
80
|
+
Considers stories with backlog, ready, or planning status.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Dict with next story details or error
|
|
84
|
+
"""
|
|
85
|
+
from pennyfarthing_scripts.sprint.loader import get_all_stories
|
|
86
|
+
|
|
87
|
+
all_stories = get_all_stories()
|
|
88
|
+
available_statuses = {"backlog", "ready", "planning"}
|
|
89
|
+
backlog = [s for s in all_stories if s.get("status") in available_statuses]
|
|
90
|
+
|
|
91
|
+
if not backlog:
|
|
92
|
+
return {
|
|
93
|
+
"available": False,
|
|
94
|
+
"error": "No stories in backlog",
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Sort by priority (P0 > P1 > P2 > P3)
|
|
98
|
+
priority_order = {"P0": 0, "P1": 1, "P2": 2, "P3": 3}
|
|
99
|
+
sorted_stories = sorted(
|
|
100
|
+
backlog,
|
|
101
|
+
key=lambda s: priority_order.get(s.get("priority", "P2"), 2),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
next_story = sorted_stories[0]
|
|
105
|
+
return {
|
|
106
|
+
"available": True,
|
|
107
|
+
"type": "next",
|
|
108
|
+
"story": next_story,
|
|
109
|
+
"title": next_story.get("title"),
|
|
110
|
+
"points": next_story.get("points"),
|
|
111
|
+
"priority": next_story.get("priority", "P2"),
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def start_work(story_id: str, *, dry_run: bool = False) -> dict[str, Any]:
|
|
116
|
+
"""Start work on a story.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
story_id: Story ID to start
|
|
120
|
+
dry_run: If True, don't make changes
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Dict with success status and details
|
|
124
|
+
"""
|
|
125
|
+
# Check availability
|
|
126
|
+
check = check_story(story_id)
|
|
127
|
+
if not check.get("available"):
|
|
128
|
+
return {
|
|
129
|
+
"success": False,
|
|
130
|
+
"error": check.get("reason") or check.get("error"),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
story = check.get("story")
|
|
134
|
+
|
|
135
|
+
if dry_run:
|
|
136
|
+
return {
|
|
137
|
+
"success": True,
|
|
138
|
+
"dry_run": True,
|
|
139
|
+
"story": story,
|
|
140
|
+
"message": f"Would start work on {story_id}",
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# In a real implementation, this would:
|
|
144
|
+
# 1. Create/update session file
|
|
145
|
+
# 2. Claim in Jira
|
|
146
|
+
# 3. Create branch
|
|
147
|
+
# For now, return success with story info
|
|
148
|
+
return {
|
|
149
|
+
"success": True,
|
|
150
|
+
"story": story,
|
|
151
|
+
"message": f"Ready to start work on {story_id}",
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def main(args: list[str] | None = None) -> int:
|
|
156
|
+
"""CLI entry point for sprint work.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
args: Command line arguments
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
Exit code
|
|
163
|
+
"""
|
|
164
|
+
import argparse
|
|
165
|
+
import sys
|
|
166
|
+
|
|
167
|
+
parser = argparse.ArgumentParser(description="Start work on a story")
|
|
168
|
+
parser.add_argument(
|
|
169
|
+
"story_id",
|
|
170
|
+
nargs="?",
|
|
171
|
+
help="Story ID (or 'next' for highest priority)",
|
|
172
|
+
)
|
|
173
|
+
parser.add_argument(
|
|
174
|
+
"--dry-run",
|
|
175
|
+
action="store_true",
|
|
176
|
+
help="Show what would be done",
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
parsed = parser.parse_args(args)
|
|
180
|
+
|
|
181
|
+
if not parsed.story_id:
|
|
182
|
+
# Show backlog
|
|
183
|
+
backlog = get_stories_by_status("backlog")
|
|
184
|
+
print(f"Available stories: {len(backlog)}")
|
|
185
|
+
for story in backlog[:10]:
|
|
186
|
+
print(f" {story.get('id')}: {story.get('title')} [{story.get('points', '?')}pts]")
|
|
187
|
+
return 0
|
|
188
|
+
|
|
189
|
+
if parsed.story_id == "next":
|
|
190
|
+
result = get_next_story()
|
|
191
|
+
else:
|
|
192
|
+
result = check_story(parsed.story_id)
|
|
193
|
+
|
|
194
|
+
if result.get("available"):
|
|
195
|
+
story = result.get("story", {})
|
|
196
|
+
print(f"Story: {story.get('id')}")
|
|
197
|
+
print(f"Title: {story.get('title')}")
|
|
198
|
+
print(f"Points: {story.get('points')}")
|
|
199
|
+
print(f"Status: Available")
|
|
200
|
+
return 0
|
|
201
|
+
else:
|
|
202
|
+
print(f"Not available: {result.get('error') or result.get('reason')}", file=sys.stderr)
|
|
203
|
+
return 1
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
if __name__ == "__main__":
|
|
207
|
+
import sys
|
|
208
|
+
sys.exit(main())
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Deterministic YAML I/O for sprint data.
|
|
3
|
+
|
|
4
|
+
Story: MSSCI-14254 - Core yaml_io module with deterministic serialization
|
|
5
|
+
|
|
6
|
+
Provides:
|
|
7
|
+
- read_sprint(path) -> CommentedMap (preserves ordering/comments, merges shards)
|
|
8
|
+
- write_sprint(path, data) -> atomic write (shard-aware)
|
|
9
|
+
- canonical_dump(data) -> deterministic YAML string
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import io
|
|
13
|
+
import os
|
|
14
|
+
import re
|
|
15
|
+
from collections.abc import Mapping
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from ruamel.yaml import YAML
|
|
20
|
+
from ruamel.yaml.comments import CommentedMap, CommentedSeq
|
|
21
|
+
from ruamel.yaml.scalarstring import LiteralScalarString
|
|
22
|
+
|
|
23
|
+
JIRA_PATTERN = re.compile(r"^MSSCI-\d{5}$")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Canonical key ordering derived from sprint-template.yaml
|
|
27
|
+
SPRINT_KEY_ORDER: list[str] = [
|
|
28
|
+
"name", "jira_sprint_id", "jira_sprint_name", "goal",
|
|
29
|
+
"start_date", "end_date", "status",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
EPIC_KEY_ORDER: list[str] = [
|
|
33
|
+
"id", "type", "title", "description", "priority", "status",
|
|
34
|
+
"repos", "jira", "points", "marker", "stories",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
STORY_KEY_ORDER: list[str] = [
|
|
38
|
+
"id", "jira", "title", "description", "points", "priority",
|
|
39
|
+
"status", "in_sprint", "assigned_to", "started", "repos",
|
|
40
|
+
"workflow", "acceptance_criteria", "completed", "pr",
|
|
41
|
+
"delivered_in", "notes",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# Top-level key ordering
|
|
45
|
+
TOP_KEY_ORDER: list[str] = ["sprint", "epics", "stories"]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _make_yaml() -> YAML:
|
|
49
|
+
"""Create a configured ruamel.yaml instance."""
|
|
50
|
+
yml = YAML()
|
|
51
|
+
yml.preserve_quotes = True
|
|
52
|
+
yml.default_flow_style = False
|
|
53
|
+
yml.indent(mapping=2, sequence=4, offset=2)
|
|
54
|
+
yml.width = 4096 # Prevent line wrapping
|
|
55
|
+
return yml
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _read_yaml_file(path: Path) -> CommentedMap:
|
|
59
|
+
"""Read a single YAML file preserving ordering and comments.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
path: Path to YAML file
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
CommentedMap with preserved ordering and comments
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
FileNotFoundError: If path doesn't exist
|
|
69
|
+
ValueError: If YAML is malformed or empty
|
|
70
|
+
"""
|
|
71
|
+
if not path.exists():
|
|
72
|
+
raise FileNotFoundError(f"Sprint YAML file not found: {path}")
|
|
73
|
+
|
|
74
|
+
yml = _make_yaml()
|
|
75
|
+
try:
|
|
76
|
+
with open(path) as f:
|
|
77
|
+
data = yml.load(f)
|
|
78
|
+
except Exception as e:
|
|
79
|
+
raise ValueError(f"Failed to parse YAML: {e}") from e
|
|
80
|
+
|
|
81
|
+
if data is None:
|
|
82
|
+
raise ValueError(f"Empty YAML file: {path}")
|
|
83
|
+
|
|
84
|
+
return data
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def read_sprint(path: Path) -> CommentedMap:
|
|
88
|
+
"""Read sprint YAML file, merging sharded epic files.
|
|
89
|
+
|
|
90
|
+
When the epics list contains string references (sharded format),
|
|
91
|
+
loads each epic-{ref}.yaml shard file and replaces the strings
|
|
92
|
+
with full epic CommentedMaps.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
path: Path to sprint YAML index file
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
CommentedMap with full epic data merged in
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
FileNotFoundError: If path doesn't exist
|
|
102
|
+
ValueError: If YAML is malformed or empty
|
|
103
|
+
"""
|
|
104
|
+
data = _read_yaml_file(path)
|
|
105
|
+
|
|
106
|
+
epics = data.get("epics", [])
|
|
107
|
+
if not epics or not isinstance(epics[0], str):
|
|
108
|
+
return data
|
|
109
|
+
|
|
110
|
+
sprint_dir = path.parent
|
|
111
|
+
merged_epics = CommentedSeq()
|
|
112
|
+
for ref in epics:
|
|
113
|
+
if isinstance(ref, str):
|
|
114
|
+
shard_file = sprint_dir / f"epic-{ref}.yaml"
|
|
115
|
+
if shard_file.exists():
|
|
116
|
+
epic_data = _read_yaml_file(shard_file)
|
|
117
|
+
merged_epics.append(epic_data)
|
|
118
|
+
else:
|
|
119
|
+
merged_epics.append(ref)
|
|
120
|
+
|
|
121
|
+
data["epics"] = merged_epics
|
|
122
|
+
return data
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _sort_mapping(data: CommentedMap, key_order: list[str]) -> CommentedMap:
|
|
126
|
+
"""Reorder keys in a CommentedMap according to key_order.
|
|
127
|
+
|
|
128
|
+
Known keys appear in template order, unknown keys are appended at the end.
|
|
129
|
+
"""
|
|
130
|
+
result = CommentedMap()
|
|
131
|
+
# First, add known keys in order
|
|
132
|
+
for key in key_order:
|
|
133
|
+
if key in data:
|
|
134
|
+
result[key] = data[key]
|
|
135
|
+
# Then add any unknown keys at the end
|
|
136
|
+
for key in data:
|
|
137
|
+
if key not in key_order:
|
|
138
|
+
result[key] = data[key]
|
|
139
|
+
return result
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _ensure_block_scalars(data: Any) -> Any:
|
|
143
|
+
"""Convert multiline strings to block scalar style recursively."""
|
|
144
|
+
if isinstance(data, CommentedMap):
|
|
145
|
+
result = CommentedMap()
|
|
146
|
+
for key, value in data.items():
|
|
147
|
+
result[key] = _ensure_block_scalars(value)
|
|
148
|
+
return result
|
|
149
|
+
elif isinstance(data, (list, CommentedSeq)):
|
|
150
|
+
result_list = CommentedSeq()
|
|
151
|
+
for item in data:
|
|
152
|
+
result_list.append(_ensure_block_scalars(item))
|
|
153
|
+
return result_list
|
|
154
|
+
elif isinstance(data, str) and "\n" in data:
|
|
155
|
+
return LiteralScalarString(data)
|
|
156
|
+
return data
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _canonicalize(data: Any) -> Any:
|
|
160
|
+
"""Apply canonical ordering and formatting to sprint data recursively."""
|
|
161
|
+
if not isinstance(data, Mapping):
|
|
162
|
+
return data
|
|
163
|
+
|
|
164
|
+
# Determine which key order to use based on context
|
|
165
|
+
# Top level
|
|
166
|
+
result = _sort_mapping(
|
|
167
|
+
data if isinstance(data, CommentedMap) else _to_commented_map(data),
|
|
168
|
+
TOP_KEY_ORDER,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Reorder sprint section
|
|
172
|
+
if "sprint" in result and isinstance(result["sprint"], Mapping):
|
|
173
|
+
sprint_cm = (
|
|
174
|
+
result["sprint"]
|
|
175
|
+
if isinstance(result["sprint"], CommentedMap)
|
|
176
|
+
else _to_commented_map(result["sprint"])
|
|
177
|
+
)
|
|
178
|
+
result["sprint"] = _sort_mapping(sprint_cm, SPRINT_KEY_ORDER)
|
|
179
|
+
|
|
180
|
+
# Reorder epics and their stories
|
|
181
|
+
if "epics" in result and isinstance(result["epics"], (list, CommentedSeq)):
|
|
182
|
+
new_epics = CommentedSeq()
|
|
183
|
+
for epic in result["epics"]:
|
|
184
|
+
if isinstance(epic, Mapping):
|
|
185
|
+
epic_cm = (
|
|
186
|
+
epic if isinstance(epic, CommentedMap) else _to_commented_map(epic)
|
|
187
|
+
)
|
|
188
|
+
sorted_epic = _sort_mapping(epic_cm, EPIC_KEY_ORDER)
|
|
189
|
+
|
|
190
|
+
# Reorder stories within epic
|
|
191
|
+
if "stories" in sorted_epic and isinstance(
|
|
192
|
+
sorted_epic["stories"], (list, CommentedSeq)
|
|
193
|
+
):
|
|
194
|
+
new_stories = CommentedSeq()
|
|
195
|
+
for story in sorted_epic["stories"]:
|
|
196
|
+
if isinstance(story, Mapping):
|
|
197
|
+
story_cm = (
|
|
198
|
+
story
|
|
199
|
+
if isinstance(story, CommentedMap)
|
|
200
|
+
else _to_commented_map(story)
|
|
201
|
+
)
|
|
202
|
+
new_stories.append(
|
|
203
|
+
_sort_mapping(story_cm, STORY_KEY_ORDER)
|
|
204
|
+
)
|
|
205
|
+
else:
|
|
206
|
+
new_stories.append(story)
|
|
207
|
+
sorted_epic["stories"] = new_stories
|
|
208
|
+
|
|
209
|
+
new_epics.append(sorted_epic)
|
|
210
|
+
else:
|
|
211
|
+
new_epics.append(epic)
|
|
212
|
+
result["epics"] = new_epics
|
|
213
|
+
|
|
214
|
+
# Apply block scalars to multiline strings
|
|
215
|
+
result = _ensure_block_scalars(result)
|
|
216
|
+
|
|
217
|
+
return result
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _to_commented_map(data: Mapping) -> CommentedMap:
|
|
221
|
+
"""Convert a plain dict to CommentedMap recursively."""
|
|
222
|
+
result = CommentedMap()
|
|
223
|
+
for key, value in data.items():
|
|
224
|
+
if isinstance(value, dict):
|
|
225
|
+
result[key] = _to_commented_map(value)
|
|
226
|
+
elif isinstance(value, list):
|
|
227
|
+
seq = CommentedSeq()
|
|
228
|
+
for item in value:
|
|
229
|
+
if isinstance(item, dict):
|
|
230
|
+
seq.append(_to_commented_map(item))
|
|
231
|
+
else:
|
|
232
|
+
seq.append(item)
|
|
233
|
+
result[key] = seq
|
|
234
|
+
else:
|
|
235
|
+
result[key] = value
|
|
236
|
+
return result
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def canonical_dump(data: Any) -> str:
|
|
240
|
+
"""Serialize sprint data to deterministic YAML string.
|
|
241
|
+
|
|
242
|
+
Applies:
|
|
243
|
+
- Fixed key ordering per sprint-template.yaml
|
|
244
|
+
- Block scalars (|) for multiline strings
|
|
245
|
+
- 2-space indentation
|
|
246
|
+
- No trailing whitespace
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
data: Sprint data (CommentedMap or dict)
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
Deterministic YAML string
|
|
253
|
+
"""
|
|
254
|
+
canonicalized = _canonicalize(data)
|
|
255
|
+
|
|
256
|
+
yml = _make_yaml()
|
|
257
|
+
stream = io.StringIO()
|
|
258
|
+
yml.dump(canonicalized, stream)
|
|
259
|
+
output = stream.getvalue()
|
|
260
|
+
|
|
261
|
+
# Strip trailing whitespace from each line
|
|
262
|
+
lines = output.split("\n")
|
|
263
|
+
cleaned = [line.rstrip() for line in lines]
|
|
264
|
+
result = "\n".join(cleaned)
|
|
265
|
+
|
|
266
|
+
# Ensure exactly one trailing newline
|
|
267
|
+
result = result.rstrip("\n") + "\n"
|
|
268
|
+
|
|
269
|
+
return result
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _get_epic_ref(epic: Mapping) -> str:
|
|
273
|
+
"""Get the canonical reference ID for an epic shard file.
|
|
274
|
+
|
|
275
|
+
Mirrors the logic in migrate-to-shards.py: prefer Jira key, fall back to ID.
|
|
276
|
+
"""
|
|
277
|
+
jira = epic.get("jira")
|
|
278
|
+
epic_id = str(epic.get("id", ""))
|
|
279
|
+
|
|
280
|
+
if jira and JIRA_PATTERN.match(str(jira)):
|
|
281
|
+
return str(jira)
|
|
282
|
+
if JIRA_PATTERN.match(epic_id):
|
|
283
|
+
return epic_id
|
|
284
|
+
return epic_id
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _write_yaml_file(path: Path, data: Any) -> None:
|
|
288
|
+
"""Write data to a single YAML file atomically.
|
|
289
|
+
|
|
290
|
+
Uses temp file + os.replace() for atomic writes on POSIX.
|
|
291
|
+
"""
|
|
292
|
+
if not isinstance(data, Mapping):
|
|
293
|
+
raise TypeError(f"Expected mapping type, got {type(data).__name__}")
|
|
294
|
+
|
|
295
|
+
output = canonical_dump(data)
|
|
296
|
+
|
|
297
|
+
tmp_path = path.with_suffix(".yaml.tmp")
|
|
298
|
+
try:
|
|
299
|
+
with open(tmp_path, "w") as f:
|
|
300
|
+
f.write(output)
|
|
301
|
+
os.replace(tmp_path, path)
|
|
302
|
+
except Exception:
|
|
303
|
+
if tmp_path.exists():
|
|
304
|
+
tmp_path.unlink()
|
|
305
|
+
raise
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def _is_sharded_on_disk(path: Path) -> bool:
|
|
309
|
+
"""Check if the on-disk index file uses sharded epic references."""
|
|
310
|
+
if not path.exists():
|
|
311
|
+
return False
|
|
312
|
+
yml = _make_yaml()
|
|
313
|
+
try:
|
|
314
|
+
with open(path) as f:
|
|
315
|
+
on_disk = yml.load(f)
|
|
316
|
+
except Exception:
|
|
317
|
+
return False
|
|
318
|
+
if on_disk is None or not isinstance(on_disk, Mapping):
|
|
319
|
+
return False
|
|
320
|
+
epics = on_disk.get("epics", [])
|
|
321
|
+
return bool(epics) and isinstance(epics[0], str)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def write_sprint(path: Path, data: Any) -> None:
|
|
325
|
+
"""Write sprint data to YAML file(s) atomically.
|
|
326
|
+
|
|
327
|
+
If the on-disk index uses sharded format (epics as string refs),
|
|
328
|
+
writes each epic to its shard file and the index with string refs.
|
|
329
|
+
Otherwise writes the full data to a single file.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
path: Destination path (the index file)
|
|
333
|
+
data: Sprint data (CommentedMap or dict)
|
|
334
|
+
|
|
335
|
+
Raises:
|
|
336
|
+
TypeError: If data is not a valid mapping type
|
|
337
|
+
OSError: If write fails
|
|
338
|
+
"""
|
|
339
|
+
if not isinstance(data, Mapping):
|
|
340
|
+
raise TypeError(f"Expected mapping type, got {type(data).__name__}")
|
|
341
|
+
|
|
342
|
+
if not _is_sharded_on_disk(path):
|
|
343
|
+
_write_yaml_file(path, data)
|
|
344
|
+
return
|
|
345
|
+
|
|
346
|
+
# Sharded write: each epic goes to its own file
|
|
347
|
+
sprint_dir = path.parent
|
|
348
|
+
epic_refs = CommentedSeq()
|
|
349
|
+
|
|
350
|
+
for epic in data.get("epics", []):
|
|
351
|
+
if isinstance(epic, Mapping):
|
|
352
|
+
ref = _get_epic_ref(epic)
|
|
353
|
+
shard_file = sprint_dir / f"epic-{ref}.yaml"
|
|
354
|
+
_write_yaml_file(shard_file, epic)
|
|
355
|
+
epic_refs.append(ref)
|
|
356
|
+
else:
|
|
357
|
+
epic_refs.append(epic)
|
|
358
|
+
|
|
359
|
+
# Write index with string refs instead of full epic dicts
|
|
360
|
+
index = CommentedMap()
|
|
361
|
+
for key in data:
|
|
362
|
+
if key == "epics":
|
|
363
|
+
index["epics"] = epic_refs
|
|
364
|
+
else:
|
|
365
|
+
index[key] = data[key]
|
|
366
|
+
|
|
367
|
+
_write_yaml_file(path, index)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Story management package for Pennyfarthing scripts.
|
|
3
|
+
|
|
4
|
+
This package provides:
|
|
5
|
+
- size: Story sizing guidelines
|
|
6
|
+
- template: Story templates
|
|
7
|
+
- create: Story creation
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
# Use the modules
|
|
11
|
+
from pennyfarthing_scripts.story import get_sizing_guidelines, get_template
|
|
12
|
+
|
|
13
|
+
# Use CLI
|
|
14
|
+
python -m pennyfarthing_scripts.story <subcommand> [args]
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Re-export common functions
|
|
18
|
+
from pennyfarthing_scripts.story.size import (
|
|
19
|
+
SIZING_GUIDELINES,
|
|
20
|
+
format_size_info,
|
|
21
|
+
get_sizing_guidelines,
|
|
22
|
+
)
|
|
23
|
+
from pennyfarthing_scripts.story.template import (
|
|
24
|
+
TEMPLATES,
|
|
25
|
+
format_template,
|
|
26
|
+
get_all_templates,
|
|
27
|
+
get_template,
|
|
28
|
+
)
|
|
29
|
+
from pennyfarthing_scripts.story.create import (
|
|
30
|
+
create_story,
|
|
31
|
+
generate_story_yaml,
|
|
32
|
+
validate_points,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Import submodules
|
|
36
|
+
from pennyfarthing_scripts.story import (
|
|
37
|
+
create,
|
|
38
|
+
size,
|
|
39
|
+
template,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# CLI entry point - import module, not function, so "from story import cli" gets the module
|
|
43
|
+
from pennyfarthing_scripts.story import cli
|
|
44
|
+
from pennyfarthing_scripts.story.cli import main
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
# Size
|
|
48
|
+
"SIZING_GUIDELINES",
|
|
49
|
+
"format_size_info",
|
|
50
|
+
"get_sizing_guidelines",
|
|
51
|
+
# Template
|
|
52
|
+
"TEMPLATES",
|
|
53
|
+
"format_template",
|
|
54
|
+
"get_all_templates",
|
|
55
|
+
"get_template",
|
|
56
|
+
# Create
|
|
57
|
+
"create_story",
|
|
58
|
+
"generate_story_yaml",
|
|
59
|
+
"validate_points",
|
|
60
|
+
# Submodules
|
|
61
|
+
"create",
|
|
62
|
+
"size",
|
|
63
|
+
"template",
|
|
64
|
+
# CLI
|
|
65
|
+
"cli",
|
|
66
|
+
"main",
|
|
67
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|