@pennyfarthing/core 11.2.2 → 11.3.1
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 +3 -3
- package/package.json +1 -1
- package/packages/core/dist/cli/commands/doctor-legacy.test.js +2 -2
- package/packages/core/dist/cli/commands/doctor-legacy.test.js.map +1 -1
- package/packages/core/dist/cli/commands/doctor.d.ts +55 -0
- package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/doctor.js +204 -23
- package/packages/core/dist/cli/commands/doctor.js.map +1 -1
- package/packages/core/dist/cli/commands/init.d.ts +12 -0
- package/packages/core/dist/cli/commands/init.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/init.js +45 -0
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/pyproject-install.test.d.ts +19 -0
- package/packages/core/dist/cli/commands/pyproject-install.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/pyproject-install.test.js +261 -0
- package/packages/core/dist/cli/commands/pyproject-install.test.js.map +1 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts +17 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.d.ts.map +1 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js +470 -0
- package/packages/core/dist/cli/commands/stale-artifacts-cleanup.test.js.map +1 -0
- package/packages/core/dist/cli/commands/update-consolidation.test.js +14 -6
- package/packages/core/dist/cli/commands/update-consolidation.test.js.map +1 -1
- package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/update.js +31 -2
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/packages/core/dist/cli/cyclist-migration.test.d.ts +16 -0
- package/packages/core/dist/cli/cyclist-migration.test.d.ts.map +1 -0
- package/packages/core/dist/cli/cyclist-migration.test.js +229 -0
- package/packages/core/dist/cli/cyclist-migration.test.js.map +1 -0
- package/packages/core/dist/cli/index.js +2 -0
- package/packages/core/dist/cli/index.js.map +1 -1
- package/packages/core/dist/cli/utils/python.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/python.js +11 -0
- package/packages/core/dist/cli/utils/python.js.map +1 -1
- package/packages/core/dist/cli/utils/settings-hook-migration.test.d.ts +17 -0
- package/packages/core/dist/cli/utils/settings-hook-migration.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/settings-hook-migration.test.js +382 -0
- package/packages/core/dist/cli/utils/settings-hook-migration.test.js.map +1 -0
- package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/settings.js +15 -2
- package/packages/core/dist/cli/utils/settings.js.map +1 -1
- package/packages/core/dist/cli/utils/stale-artifacts.d.ts +59 -0
- package/packages/core/dist/cli/utils/stale-artifacts.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/stale-artifacts.js +163 -0
- package/packages/core/dist/cli/utils/stale-artifacts.js.map +1 -0
- package/packages/core/dist/scripts/benchmark-integration.d.ts +182 -0
- package/packages/core/dist/scripts/benchmark-integration.d.ts.map +1 -0
- package/packages/core/dist/scripts/benchmark-integration.js +691 -0
- package/packages/core/dist/scripts/benchmark-integration.js.map +1 -0
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts +150 -0
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +1 -0
- package/packages/core/dist/scripts/job-fair-aggregator.js +547 -0
- package/packages/core/dist/scripts/job-fair-aggregator.js.map +1 -0
- package/packages/core/dist/scripts/theme-detail.test.d.ts.map +1 -0
- package/packages/core/dist/scripts/theme-detail.test.js.map +1 -0
- package/packages/core/dist/server/settings.d.ts.map +1 -1
- package/packages/core/dist/server/settings.js +5 -0
- package/packages/core/dist/server/settings.js.map +1 -1
- package/packages/core/dist/workflow/tandem-workflow-templates.test.js +7 -5
- package/packages/core/dist/workflow/tandem-workflow-templates.test.js.map +1 -1
- package/packages/core/dist/workflow/workflow-migration.test.js +6 -5
- package/packages/core/dist/workflow/workflow-migration.test.js.map +1 -1
- package/pennyfarthing-dist/agents/dev.md +4 -2
- package/pennyfarthing-dist/agents/devops.md +2 -10
- package/pennyfarthing-dist/agents/reviewer-preflight.md +4 -5
- package/pennyfarthing-dist/agents/sm.md +4 -17
- package/pennyfarthing-dist/commands/pf-health-check.md +30 -11
- package/pennyfarthing-dist/gates/{confidence-sm.md → confidence.md} +16 -17
- package/pennyfarthing-dist/gates/dev-exit.md +75 -0
- package/pennyfarthing-dist/gates/merge-ready.md +49 -0
- package/pennyfarthing-dist/gates/release-ready.md +95 -0
- package/pennyfarthing-dist/gates/reviewer-preflight-check.md +90 -0
- package/pennyfarthing-dist/gates/sm-setup-exit.md +82 -0
- package/pennyfarthing-dist/guides/agent-behavior.md +88 -30
- package/pennyfarthing-dist/guides/gates.md +7 -2
- package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/scripts/lib/find-root.sh +5 -0
- package/pennyfarthing-dist/scripts/lib/run-pf.sh +4 -0
- package/pennyfarthing-dist/skills/pf-settings/skill.md +42 -0
- package/pennyfarthing-dist/skills/skill-registry.yaml +15 -0
- package/pennyfarthing-dist/templates/pyproject.toml +27 -0
- package/pennyfarthing-dist/workflows/bdd-tandem.yaml +7 -3
- package/pennyfarthing-dist/workflows/bdd.yaml +7 -3
- package/pennyfarthing-dist/workflows/installation-check/steps/step-01-foundation.md +77 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-02-commands.md +82 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-03-hooks.md +121 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-04-scripts.md +83 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-05-layout.md +81 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-06-legacy.md +94 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-07-tools.md +80 -0
- package/pennyfarthing-dist/workflows/installation-check/steps/step-08-summary.md +99 -0
- package/pennyfarthing-dist/workflows/installation-check/workflow.yaml +47 -0
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +7 -3
- package/pennyfarthing-dist/workflows/tdd.yaml +7 -3
- package/pennyfarthing-dist/workflows/trivial.yaml +7 -3
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/cli.cpython-311.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__/context.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/context.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__/session_start_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/bc/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/split.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/cli.py +21 -0
- package/pennyfarthing_scripts/bc/focus.py +1 -0
- package/pennyfarthing_scripts/bc/split.py +52 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/audit_log_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/context_meter_footer.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/events.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/portrait_resolver.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_data.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/story_detail_screen.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/context_meter_footer.py +53 -3
- package/pennyfarthing_scripts/bikerack/tui.py +202 -8
- 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/cli.py +5 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/config.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/output.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/pr_config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/consultation/__pycache__/dialogue_manager.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -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_group/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/phase_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/session_start.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/session_start.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/session_stop.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/sprint_yaml_validation.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/sprint_yaml_validation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-311.pyc +0 -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-311.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-311.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-311.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-311.pyc +0 -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-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/client.cpython-311.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-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-311.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-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/story.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -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/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/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__/version_sentinel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/settings/__init__.py +0 -0
- package/pennyfarthing_scripts/settings/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/settings/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/settings/__pycache__/settings.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/settings/cli.py +55 -0
- package/pennyfarthing_scripts/settings/settings.py +98 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-311.pyc +0 -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-311.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-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -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/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_108_1_gate_migration.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.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_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.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_confidence_sm_evaluation.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_confidence_sm_gate.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_dialogue_manager.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.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_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.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_panel.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_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.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_version_sentinel.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/test_confidence_sm_gate.py +17 -16
- package/pennyfarthing_scripts/tests/test_resolve_gate_file_field.py +45 -47
- package/pennyfarthing_scripts/tests/test_workflow_list_team.py +0 -4
- package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/packages/core/dist/workflow/team-lifecycle.d.ts +0 -169
- package/packages/core/dist/workflow/team-lifecycle.d.ts.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.js +0 -217
- package/packages/core/dist/workflow/team-lifecycle.js.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.test.d.ts +0 -20
- package/packages/core/dist/workflow/team-lifecycle.test.d.ts.map +0 -1
- package/packages/core/dist/workflow/team-lifecycle.test.js +0 -966
- package/packages/core/dist/workflow/team-lifecycle.test.js.map +0 -1
- package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/__pycache__/validate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_108_2_remove_handoff_fallback.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_list_team.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/team_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/team_lifecycle.cpython-314.pyc +0 -0
|
@@ -6,7 +6,7 @@ Story: 106-3 — Workflow YAML gate.file integration
|
|
|
6
6
|
Tests the gate.file field support in resolve_gate():
|
|
7
7
|
- Schema extension: gate.file extracted from workflow YAML
|
|
8
8
|
- Backward compatibility: gate.type-only workflows unchanged
|
|
9
|
-
- TDD workflow migration:
|
|
9
|
+
- TDD workflow migration: all phases now have gate.file fields
|
|
10
10
|
|
|
11
11
|
Acceptance Criteria:
|
|
12
12
|
- [AC1] resolve-gate.py reads gate.file field from workflow YAML phases
|
|
@@ -15,9 +15,9 @@ Acceptance Criteria:
|
|
|
15
15
|
- [AC2] Workflows with only gate.type continue to work unchanged
|
|
16
16
|
- [AC2] Existing gate type logic remains functional
|
|
17
17
|
- [AC2] No breaking changes to resolve-gate API
|
|
18
|
-
- [AC3] Green phase in tdd.yaml has file: gates/
|
|
19
|
-
- [AC3]
|
|
20
|
-
- [AC3] File
|
|
18
|
+
- [AC3] Green phase in tdd.yaml has file: gates/dev-exit and type: dev_exit
|
|
19
|
+
- [AC3] All phases have gate.file fields (full migration complete)
|
|
20
|
+
- [AC3] File paths are relative (not absolute)
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
from __future__ import annotations
|
|
@@ -202,21 +202,19 @@ class TestResolveGateFileOnly:
|
|
|
202
202
|
)
|
|
203
203
|
assert result["gate_type"] is None
|
|
204
204
|
|
|
205
|
-
def
|
|
205
|
+
def test_status_ready_when_no_type_and_file_only(
|
|
206
206
|
self, project: Path
|
|
207
207
|
) -> None:
|
|
208
|
-
"""AC1: gate with file-only and no type → status
|
|
208
|
+
"""AC1: gate with file-only and no type → status is 'ready'.
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
So file-only gates (no type) currently get 'skip' status.
|
|
214
|
-
This is expected during migration — consumers check gate_file separately.
|
|
210
|
+
File-only gates (no type) are resolvable — the gate runner uses
|
|
211
|
+
gate_file to locate and execute the gate. Status is 'ready' when
|
|
212
|
+
an assessment exists.
|
|
215
213
|
"""
|
|
216
214
|
result = resolve_gate(
|
|
217
215
|
"106-3", "file-only", "green", project_root=project
|
|
218
216
|
)
|
|
219
|
-
assert result["status"] == "
|
|
217
|
+
assert result["status"] == "ready"
|
|
220
218
|
|
|
221
219
|
|
|
222
220
|
# ===========================================================================
|
|
@@ -315,11 +313,10 @@ class TestResolveGateBackwardCompat:
|
|
|
315
313
|
|
|
316
314
|
|
|
317
315
|
class TestTddWorkflowMigration:
|
|
318
|
-
"""AC3: TDD workflow
|
|
316
|
+
"""AC3: TDD workflow phases have gate.file fields after full migration.
|
|
319
317
|
|
|
320
318
|
These tests read the ACTUAL tdd.yaml from the project to verify
|
|
321
|
-
the migration has been applied.
|
|
322
|
-
updates tdd.yaml.
|
|
319
|
+
the migration has been applied.
|
|
323
320
|
"""
|
|
324
321
|
|
|
325
322
|
@pytest.fixture
|
|
@@ -342,54 +339,55 @@ class TestTddWorkflowMigration:
|
|
|
342
339
|
raise ValueError(f"Phase '{name}' not found")
|
|
343
340
|
|
|
344
341
|
def test_green_phase_has_gate_file(self, tdd_yaml: dict) -> None:
|
|
345
|
-
"""AC3: Green phase should have gate.file = 'gates/
|
|
342
|
+
"""AC3: Green phase should have gate.file = 'gates/dev-exit'."""
|
|
346
343
|
green = self._get_phase(tdd_yaml, "green")
|
|
347
344
|
gate = green.get("gate", {})
|
|
348
|
-
assert gate.get("file") == "gates/
|
|
349
|
-
f"Expected gate.file='gates/
|
|
345
|
+
assert gate.get("file") == "gates/dev-exit", (
|
|
346
|
+
f"Expected gate.file='gates/dev-exit', got gate={gate}"
|
|
350
347
|
)
|
|
351
348
|
|
|
352
|
-
def
|
|
353
|
-
"""AC3: Green phase should
|
|
349
|
+
def test_green_phase_has_dev_exit_type(self, tdd_yaml: dict) -> None:
|
|
350
|
+
"""AC3: Green phase should have gate.type = 'dev_exit'."""
|
|
354
351
|
green = self._get_phase(tdd_yaml, "green")
|
|
355
352
|
gate = green.get("gate", {})
|
|
356
|
-
assert gate.get("type") == "
|
|
357
|
-
f"Expected gate.type='
|
|
353
|
+
assert gate.get("type") == "dev_exit", (
|
|
354
|
+
f"Expected gate.type='dev_exit', got gate={gate}"
|
|
358
355
|
)
|
|
359
356
|
|
|
360
357
|
def test_green_phase_file_is_relative(self, tdd_yaml: dict) -> None:
|
|
361
|
-
"""AC3: File path should be relative (gates/
|
|
358
|
+
"""AC3: File path should be relative (gates/dev-exit), not absolute."""
|
|
362
359
|
green = self._get_phase(tdd_yaml, "green")
|
|
363
360
|
gate = green.get("gate", {})
|
|
364
361
|
file_path = gate.get("file", "")
|
|
365
362
|
assert not file_path.startswith("/"), (
|
|
366
363
|
f"gate.file should be relative, got: {file_path}"
|
|
367
364
|
)
|
|
368
|
-
assert file_path == "gates/
|
|
369
|
-
f"Expected 'gates/
|
|
365
|
+
assert file_path == "gates/dev-exit", (
|
|
366
|
+
f"Expected 'gates/dev-exit', got: {file_path}"
|
|
370
367
|
)
|
|
371
368
|
|
|
372
|
-
def
|
|
373
|
-
"""AC3: Red phase should
|
|
369
|
+
def test_red_phase_has_gate_file(self, tdd_yaml: dict) -> None:
|
|
370
|
+
"""AC3: Red phase should have gate.file = 'gates/tests-fail'."""
|
|
374
371
|
red = self._get_phase(tdd_yaml, "red")
|
|
375
372
|
gate = red.get("gate", {})
|
|
376
|
-
assert "file"
|
|
377
|
-
f"
|
|
373
|
+
assert gate.get("file") == "gates/tests-fail", (
|
|
374
|
+
f"Expected gate.file='gates/tests-fail', got gate={gate}"
|
|
378
375
|
)
|
|
379
376
|
|
|
380
|
-
def
|
|
381
|
-
"""AC3: Review phase should
|
|
377
|
+
def test_review_phase_has_gate_file(self, tdd_yaml: dict) -> None:
|
|
378
|
+
"""AC3: Review phase should have gate.file = 'gates/approval'."""
|
|
382
379
|
review = self._get_phase(tdd_yaml, "review")
|
|
383
380
|
gate = review.get("gate", {})
|
|
384
|
-
assert "file"
|
|
385
|
-
f"
|
|
381
|
+
assert gate.get("file") == "gates/approval", (
|
|
382
|
+
f"Expected gate.file='gates/approval', got gate={gate}"
|
|
386
383
|
)
|
|
387
384
|
|
|
388
|
-
def
|
|
389
|
-
"""AC3: Setup phase should
|
|
385
|
+
def test_setup_phase_has_gate(self, tdd_yaml: dict) -> None:
|
|
386
|
+
"""AC3: Setup phase should have gate.file = 'gates/sm-setup-exit'."""
|
|
390
387
|
setup = self._get_phase(tdd_yaml, "setup")
|
|
391
|
-
|
|
392
|
-
|
|
388
|
+
gate = setup.get("gate", {})
|
|
389
|
+
assert gate.get("file") == "gates/sm-setup-exit", (
|
|
390
|
+
f"Expected gate.file='gates/sm-setup-exit', got gate={gate}"
|
|
393
391
|
)
|
|
394
392
|
|
|
395
393
|
def test_finish_phase_unchanged(self, tdd_yaml: dict) -> None:
|
|
@@ -435,30 +433,30 @@ class TestResolveGateWithRealTddYaml:
|
|
|
435
433
|
def test_green_phase_returns_gate_file(
|
|
436
434
|
self, real_project: Path
|
|
437
435
|
) -> None:
|
|
438
|
-
"""AC3: resolve_gate for tdd/green should return gate_file='gates/
|
|
436
|
+
"""AC3: resolve_gate for tdd/green should return gate_file='gates/dev-exit'."""
|
|
439
437
|
result = resolve_gate(
|
|
440
438
|
"106-3", "tdd", "green", project_root=real_project
|
|
441
439
|
)
|
|
442
|
-
assert result["gate_file"] == "gates/
|
|
443
|
-
f"Expected gate_file='gates/
|
|
440
|
+
assert result["gate_file"] == "gates/dev-exit", (
|
|
441
|
+
f"Expected gate_file='gates/dev-exit', got: {result}"
|
|
444
442
|
)
|
|
445
443
|
|
|
446
|
-
def
|
|
444
|
+
def test_green_phase_returns_dev_exit_type(
|
|
447
445
|
self, real_project: Path
|
|
448
446
|
) -> None:
|
|
449
|
-
"""AC3: resolve_gate for tdd/green should
|
|
447
|
+
"""AC3: resolve_gate for tdd/green should return gate_type='dev_exit'."""
|
|
450
448
|
result = resolve_gate(
|
|
451
449
|
"106-3", "tdd", "green", project_root=real_project
|
|
452
450
|
)
|
|
453
|
-
assert result["gate_type"] == "
|
|
454
|
-
f"Expected gate_type='
|
|
451
|
+
assert result["gate_type"] == "dev_exit", (
|
|
452
|
+
f"Expected gate_type='dev_exit', got: {result}"
|
|
455
453
|
)
|
|
456
454
|
|
|
457
|
-
def
|
|
455
|
+
def test_red_phase_gate_file_is_tests_fail(
|
|
458
456
|
self, real_project: Path
|
|
459
457
|
) -> None:
|
|
460
|
-
"""AC3: resolve_gate for tdd/red should have gate_file=
|
|
458
|
+
"""AC3: resolve_gate for tdd/red should have gate_file='gates/tests-fail'."""
|
|
461
459
|
result = resolve_gate(
|
|
462
460
|
"106-3", "tdd", "red", project_root=real_project
|
|
463
461
|
)
|
|
464
|
-
assert result["gate_file"]
|
|
462
|
+
assert result["gate_file"] == "gates/tests-fail"
|
|
@@ -17,11 +17,7 @@ workflow list team indicator are implemented.
|
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
from unittest.mock import patch
|
|
22
|
-
|
|
23
20
|
import pytest
|
|
24
|
-
import yaml
|
|
25
21
|
from click.testing import CliRunner
|
|
26
22
|
|
|
27
23
|
from pennyfarthing_scripts.cli import cli
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/pennyfarthing_scripts/validate/adapters/__pycache__/tandem_awareness.cpython-314.pyc
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-scoped Team Lifecycle for Story 86-10
|
|
3
|
-
*
|
|
4
|
-
* Manages the lifecycle of native Agent Teams within workflow phases.
|
|
5
|
-
* When a workflow phase has a `team:` config block, the lead agent creates
|
|
6
|
-
* a team at phase start, spawns teammates, and cleans up before handoff.
|
|
7
|
-
*
|
|
8
|
-
* Follows the same ProcessAdapter injection pattern as tandem-lifecycle.ts.
|
|
9
|
-
*/
|
|
10
|
-
import type { WorkflowPhase, TeamConfig } from './workflow-schema.js';
|
|
11
|
-
/** Handle to an active team for a workflow phase */
|
|
12
|
-
export interface TeamHandle {
|
|
13
|
-
/** Team name (format: {storyId}-{phase}) */
|
|
14
|
-
teamName: string;
|
|
15
|
-
/** Story ID this team belongs to */
|
|
16
|
-
storyId: string;
|
|
17
|
-
/** Workflow phase name */
|
|
18
|
-
phase: string;
|
|
19
|
-
/** Active teammate handles */
|
|
20
|
-
teammates: TeammateHandle[];
|
|
21
|
-
/** ISO timestamp when team was created */
|
|
22
|
-
createdAt: string;
|
|
23
|
-
}
|
|
24
|
-
/** Handle to an individual teammate within a team */
|
|
25
|
-
export interface TeammateHandle {
|
|
26
|
-
/** Agent name (e.g., 'architect', 'tea') */
|
|
27
|
-
agent: string;
|
|
28
|
-
/** Task description from workflow YAML */
|
|
29
|
-
task?: string;
|
|
30
|
-
/** Current teammate status */
|
|
31
|
-
status: 'spawned' | 'active' | 'idle' | 'crashed' | 'shutdown';
|
|
32
|
-
}
|
|
33
|
-
/** Parameters for creating a phase-scoped team */
|
|
34
|
-
export interface CreateTeamParams {
|
|
35
|
-
/** Phase config (must have team block to create) */
|
|
36
|
-
phase: WorkflowPhase;
|
|
37
|
-
/** Current story ID */
|
|
38
|
-
storyId: string;
|
|
39
|
-
/** Path to .session directory */
|
|
40
|
-
sessionDir: string;
|
|
41
|
-
/** Process adapter for real team operations. Omit for in-memory (tests). */
|
|
42
|
-
adapter?: TeamProcessAdapter;
|
|
43
|
-
}
|
|
44
|
-
/** Result of a gate check (TaskCompleted or TeammateIdle hook) */
|
|
45
|
-
export interface GateCheckResult {
|
|
46
|
-
/** Whether the gate passed */
|
|
47
|
-
passed: boolean;
|
|
48
|
-
/** Gate type that was checked */
|
|
49
|
-
gate: string;
|
|
50
|
-
/** Reason for pass/fail */
|
|
51
|
-
reason?: string;
|
|
52
|
-
}
|
|
53
|
-
/** Team activity summary for session file audit trail */
|
|
54
|
-
export interface TeamActivitySummary {
|
|
55
|
-
/** Team name */
|
|
56
|
-
teamName: string;
|
|
57
|
-
/** Story ID */
|
|
58
|
-
storyId: string;
|
|
59
|
-
/** Phase name */
|
|
60
|
-
phase: string;
|
|
61
|
-
/** Member details */
|
|
62
|
-
members: Array<{
|
|
63
|
-
agent: string;
|
|
64
|
-
status: string;
|
|
65
|
-
task?: string;
|
|
66
|
-
}>;
|
|
67
|
-
/** Whether all teammates were cleaned up properly */
|
|
68
|
-
cleanShutdown: boolean;
|
|
69
|
-
}
|
|
70
|
-
/** Sidecar lock handle */
|
|
71
|
-
export interface SidecarLock {
|
|
72
|
-
/** Path to the lock file */
|
|
73
|
-
lockPath: string;
|
|
74
|
-
/** Story ID that owns the lock */
|
|
75
|
-
storyId: string;
|
|
76
|
-
/** Timestamp when lock was acquired */
|
|
77
|
-
acquiredAt: string;
|
|
78
|
-
}
|
|
79
|
-
/** Standard result object per framework pattern */
|
|
80
|
-
export interface TeamResult<T = unknown> {
|
|
81
|
-
success: boolean;
|
|
82
|
-
data?: T;
|
|
83
|
-
error?: string;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Adapter for real team operations.
|
|
87
|
-
*
|
|
88
|
-
* The library module cannot call Claude Code's TeamCreate/SendMessage tools
|
|
89
|
-
* directly — callers inject the real implementation.
|
|
90
|
-
* Tests use the default no-op adapter.
|
|
91
|
-
*/
|
|
92
|
-
export interface TeamProcessAdapter {
|
|
93
|
-
/** Create a team. Returns team name. */
|
|
94
|
-
createTeam(params: {
|
|
95
|
-
teamName: string;
|
|
96
|
-
description?: string;
|
|
97
|
-
}): Promise<{
|
|
98
|
-
teamName: string;
|
|
99
|
-
}>;
|
|
100
|
-
/** Delete a team. */
|
|
101
|
-
deleteTeam(teamName: string): Promise<void>;
|
|
102
|
-
/** Spawn a teammate within a team. */
|
|
103
|
-
spawnTeammate(params: {
|
|
104
|
-
teamName: string;
|
|
105
|
-
agent: string;
|
|
106
|
-
prompt: string;
|
|
107
|
-
model?: string;
|
|
108
|
-
}): Promise<{
|
|
109
|
-
agentId: string;
|
|
110
|
-
}>;
|
|
111
|
-
/** Send shutdown request to a teammate. */
|
|
112
|
-
shutdownTeammate(params: {
|
|
113
|
-
teamName: string;
|
|
114
|
-
agent: string;
|
|
115
|
-
}): Promise<void>;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Reset all in-memory state. For testing only.
|
|
119
|
-
*/
|
|
120
|
-
export declare function _resetForTesting(): void;
|
|
121
|
-
/**
|
|
122
|
-
* Create a phase-scoped team.
|
|
123
|
-
*
|
|
124
|
-
* If phase has no team config, returns success with no handle (no-op).
|
|
125
|
-
* If phase has team config, creates team and returns handle.
|
|
126
|
-
*/
|
|
127
|
-
export declare function createTeam(params: CreateTeamParams): Promise<TeamResult<TeamHandle>>;
|
|
128
|
-
/**
|
|
129
|
-
* Spawn all teammates for a team based on workflow YAML config.
|
|
130
|
-
*/
|
|
131
|
-
export declare function spawnTeammates(handle: TeamHandle, config: TeamConfig, storyId: string, phase: string, adapter?: TeamProcessAdapter): Promise<TeamResult<TeammateHandle[]>>;
|
|
132
|
-
/**
|
|
133
|
-
* Shut down all active teammates in a team.
|
|
134
|
-
*/
|
|
135
|
-
export declare function shutdownAllTeammates(handle: TeamHandle, adapter?: TeamProcessAdapter): Promise<TeamResult<{
|
|
136
|
-
shutdownCount: number;
|
|
137
|
-
}>>;
|
|
138
|
-
/**
|
|
139
|
-
* Clean up a team entirely (TeamDelete).
|
|
140
|
-
* Must run before pf handoff.
|
|
141
|
-
*/
|
|
142
|
-
export declare function cleanupTeam(handle: TeamHandle, adapter?: TeamProcessAdapter): Promise<TeamResult<{
|
|
143
|
-
cleaned: boolean;
|
|
144
|
-
}>>;
|
|
145
|
-
/**
|
|
146
|
-
* Check gate condition when a TaskCompleted event fires.
|
|
147
|
-
*/
|
|
148
|
-
export declare function checkGateOnTaskCompleted(handle: TeamHandle, phase: WorkflowPhase): GateCheckResult;
|
|
149
|
-
/**
|
|
150
|
-
* Check gate condition when a TeammateIdle event fires.
|
|
151
|
-
*/
|
|
152
|
-
export declare function checkGateOnTeammateIdle(_handle: TeamHandle, teammate: TeammateHandle, phase: WorkflowPhase): GateCheckResult;
|
|
153
|
-
/**
|
|
154
|
-
* Generate a team activity summary for the session file audit trail.
|
|
155
|
-
*/
|
|
156
|
-
export declare function generateTeamSummary(handle: TeamHandle): TeamActivitySummary;
|
|
157
|
-
/**
|
|
158
|
-
* Acquire an exclusive lock for sidecar file writing.
|
|
159
|
-
*/
|
|
160
|
-
export declare function acquireSidecarLock(filePath: string, storyId: string, _timeout?: number): Promise<TeamResult<SidecarLock>>;
|
|
161
|
-
/**
|
|
162
|
-
* Release a sidecar file lock.
|
|
163
|
-
*/
|
|
164
|
-
export declare function releaseSidecarLock(lock: SidecarLock): TeamResult<void>;
|
|
165
|
-
/**
|
|
166
|
-
* Get the active team for a story, if any.
|
|
167
|
-
*/
|
|
168
|
-
export declare function getActiveTeam(storyId: string): TeamHandle | null;
|
|
169
|
-
//# sourceMappingURL=team-lifecycle.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"team-lifecycle.d.ts","sourceRoot":"","sources":["../../src/workflow/team-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-scoped Team Lifecycle for Story 86-10
|
|
3
|
-
*
|
|
4
|
-
* Manages the lifecycle of native Agent Teams within workflow phases.
|
|
5
|
-
* When a workflow phase has a `team:` config block, the lead agent creates
|
|
6
|
-
* a team at phase start, spawns teammates, and cleans up before handoff.
|
|
7
|
-
*
|
|
8
|
-
* Follows the same ProcessAdapter injection pattern as tandem-lifecycle.ts.
|
|
9
|
-
*/
|
|
10
|
-
// =============================================================================
|
|
11
|
-
// In-memory registries
|
|
12
|
-
// =============================================================================
|
|
13
|
-
/** Active teams keyed by storyId */
|
|
14
|
-
const activeTeams = new Map();
|
|
15
|
-
/** Sidecar locks keyed by file path */
|
|
16
|
-
const sidecarLocks = new Map();
|
|
17
|
-
/**
|
|
18
|
-
* Reset all in-memory state. For testing only.
|
|
19
|
-
*/
|
|
20
|
-
export function _resetForTesting() {
|
|
21
|
-
activeTeams.clear();
|
|
22
|
-
sidecarLocks.clear();
|
|
23
|
-
}
|
|
24
|
-
// =============================================================================
|
|
25
|
-
// Implementations
|
|
26
|
-
// =============================================================================
|
|
27
|
-
/**
|
|
28
|
-
* Create a phase-scoped team.
|
|
29
|
-
*
|
|
30
|
-
* If phase has no team config, returns success with no handle (no-op).
|
|
31
|
-
* If phase has team config, creates team and returns handle.
|
|
32
|
-
*/
|
|
33
|
-
export async function createTeam(params) {
|
|
34
|
-
const { phase, storyId, adapter } = params;
|
|
35
|
-
if (!phase.team) {
|
|
36
|
-
return { success: true };
|
|
37
|
-
}
|
|
38
|
-
const teamName = `${storyId}-${phase.name}`;
|
|
39
|
-
// Clean up existing team for same story
|
|
40
|
-
const existing = activeTeams.get(storyId);
|
|
41
|
-
if (existing && adapter) {
|
|
42
|
-
try {
|
|
43
|
-
await adapter.deleteTeam(existing.teamName);
|
|
44
|
-
}
|
|
45
|
-
catch { /* swallow */ }
|
|
46
|
-
activeTeams.delete(storyId);
|
|
47
|
-
}
|
|
48
|
-
const handle = {
|
|
49
|
-
teamName,
|
|
50
|
-
storyId,
|
|
51
|
-
phase: phase.name,
|
|
52
|
-
teammates: [],
|
|
53
|
-
createdAt: new Date().toISOString(),
|
|
54
|
-
};
|
|
55
|
-
if (adapter) {
|
|
56
|
-
try {
|
|
57
|
-
await adapter.createTeam({ teamName });
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
return { success: false, error: err.message };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
activeTeams.set(storyId, handle);
|
|
64
|
-
return { success: true, data: handle };
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Spawn all teammates for a team based on workflow YAML config.
|
|
68
|
-
*/
|
|
69
|
-
export async function spawnTeammates(handle, config, storyId, phase, adapter) {
|
|
70
|
-
const teammates = [];
|
|
71
|
-
for (const member of config.teammates) {
|
|
72
|
-
const teammate = {
|
|
73
|
-
agent: member.agent,
|
|
74
|
-
task: member.task,
|
|
75
|
-
status: 'spawned',
|
|
76
|
-
};
|
|
77
|
-
if (adapter) {
|
|
78
|
-
try {
|
|
79
|
-
await adapter.spawnTeammate({
|
|
80
|
-
teamName: handle.teamName,
|
|
81
|
-
agent: member.agent,
|
|
82
|
-
prompt: `pf agent start "${member.agent}"`,
|
|
83
|
-
model: config.model,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
teammate.status = 'crashed';
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
teammates.push(teammate);
|
|
91
|
-
}
|
|
92
|
-
handle.teammates = teammates;
|
|
93
|
-
// Update registry
|
|
94
|
-
if (activeTeams.has(handle.storyId)) {
|
|
95
|
-
activeTeams.set(handle.storyId, handle);
|
|
96
|
-
}
|
|
97
|
-
return { success: true, data: teammates };
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Shut down all active teammates in a team.
|
|
101
|
-
*/
|
|
102
|
-
export async function shutdownAllTeammates(handle, adapter) {
|
|
103
|
-
let shutdownCount = 0;
|
|
104
|
-
for (const teammate of handle.teammates) {
|
|
105
|
-
if (teammate.status === 'shutdown' || teammate.status === 'crashed') {
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
if (adapter) {
|
|
109
|
-
try {
|
|
110
|
-
await adapter.shutdownTeammate({
|
|
111
|
-
teamName: handle.teamName,
|
|
112
|
-
agent: teammate.agent,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
catch { /* swallow — graceful degradation */ }
|
|
116
|
-
}
|
|
117
|
-
teammate.status = 'shutdown';
|
|
118
|
-
shutdownCount++;
|
|
119
|
-
}
|
|
120
|
-
return { success: true, data: { shutdownCount } };
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Clean up a team entirely (TeamDelete).
|
|
124
|
-
* Must run before pf handoff.
|
|
125
|
-
*/
|
|
126
|
-
export async function cleanupTeam(handle, adapter) {
|
|
127
|
-
if (adapter) {
|
|
128
|
-
try {
|
|
129
|
-
await adapter.deleteTeam(handle.teamName);
|
|
130
|
-
}
|
|
131
|
-
catch { /* swallow */ }
|
|
132
|
-
}
|
|
133
|
-
activeTeams.delete(handle.storyId);
|
|
134
|
-
return { success: true, data: { cleaned: true } };
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Check gate condition when a TaskCompleted event fires.
|
|
138
|
-
*/
|
|
139
|
-
export function checkGateOnTaskCompleted(handle, phase) {
|
|
140
|
-
if (!phase.gate) {
|
|
141
|
-
return { passed: true, gate: 'none' };
|
|
142
|
-
}
|
|
143
|
-
const gateType = phase.gate.type ?? 'unknown';
|
|
144
|
-
const hasActive = handle.teammates.some((t) => t.status === 'active');
|
|
145
|
-
if (hasActive) {
|
|
146
|
-
return { passed: false, gate: gateType, reason: 'Teammates still active' };
|
|
147
|
-
}
|
|
148
|
-
return { passed: true, gate: gateType };
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Check gate condition when a TeammateIdle event fires.
|
|
152
|
-
*/
|
|
153
|
-
export function checkGateOnTeammateIdle(_handle, teammate, phase) {
|
|
154
|
-
if (!phase.gate) {
|
|
155
|
-
return { passed: true, gate: 'none' };
|
|
156
|
-
}
|
|
157
|
-
const gateType = phase.gate.type ?? 'unknown';
|
|
158
|
-
if (teammate.status === 'crashed') {
|
|
159
|
-
return { passed: false, gate: gateType, reason: 'Teammate crashed' };
|
|
160
|
-
}
|
|
161
|
-
return { passed: true, gate: gateType };
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Generate a team activity summary for the session file audit trail.
|
|
165
|
-
*/
|
|
166
|
-
export function generateTeamSummary(handle) {
|
|
167
|
-
return {
|
|
168
|
-
teamName: handle.teamName,
|
|
169
|
-
storyId: handle.storyId,
|
|
170
|
-
phase: handle.phase,
|
|
171
|
-
members: handle.teammates.map((t) => ({
|
|
172
|
-
agent: t.agent,
|
|
173
|
-
status: t.status,
|
|
174
|
-
task: t.task,
|
|
175
|
-
})),
|
|
176
|
-
cleanShutdown: handle.teammates.every((t) => t.status === 'shutdown'),
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Acquire an exclusive lock for sidecar file writing.
|
|
181
|
-
*/
|
|
182
|
-
export async function acquireSidecarLock(filePath, storyId, _timeout) {
|
|
183
|
-
const existing = sidecarLocks.get(filePath);
|
|
184
|
-
if (existing) {
|
|
185
|
-
if (existing.storyId === storyId) {
|
|
186
|
-
return { success: true, data: existing };
|
|
187
|
-
}
|
|
188
|
-
return { success: false, error: `Lock held by story ${existing.storyId}` };
|
|
189
|
-
}
|
|
190
|
-
const lock = {
|
|
191
|
-
lockPath: `${filePath}.lock`,
|
|
192
|
-
storyId,
|
|
193
|
-
acquiredAt: new Date().toISOString(),
|
|
194
|
-
};
|
|
195
|
-
sidecarLocks.set(filePath, lock);
|
|
196
|
-
return { success: true, data: lock };
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Release a sidecar file lock.
|
|
200
|
-
*/
|
|
201
|
-
export function releaseSidecarLock(lock) {
|
|
202
|
-
// Find and remove by lockPath
|
|
203
|
-
for (const [path, held] of sidecarLocks) {
|
|
204
|
-
if (held.lockPath === lock.lockPath) {
|
|
205
|
-
sidecarLocks.delete(path);
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return { success: true };
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Get the active team for a story, if any.
|
|
213
|
-
*/
|
|
214
|
-
export function getActiveTeam(storyId) {
|
|
215
|
-
return activeTeams.get(storyId) ?? null;
|
|
216
|
-
}
|
|
217
|
-
//# sourceMappingURL=team-lifecycle.js.map
|