@pennyfarthing/core 11.1.1 → 11.2.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 +8 -8
- package/package.json +2 -1
- package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/doctor.js +381 -66
- package/packages/core/dist/cli/commands/doctor.js.map +1 -1
- package/packages/core/dist/cli/commands/init.js +4 -4
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/update.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/update.js +4 -5
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/packages/core/dist/cli/utils/constants.d.ts +3 -8
- package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/constants.js +3 -4
- package/packages/core/dist/cli/utils/constants.js.map +1 -1
- package/packages/core/dist/cli/utils/settings.d.ts +11 -0
- package/packages/core/dist/cli/utils/settings.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/settings.js +65 -29
- package/packages/core/dist/cli/utils/settings.js.map +1 -1
- package/packages/core/dist/cli/utils/symlinks.js +16 -16
- package/packages/core/dist/cli/utils/symlinks.js.map +1 -1
- package/packages/core/dist/consultation/tandem-metrics.d.ts +91 -0
- package/packages/core/dist/consultation/tandem-metrics.d.ts.map +1 -0
- package/packages/core/dist/consultation/tandem-metrics.js +131 -0
- package/packages/core/dist/consultation/tandem-metrics.js.map +1 -0
- package/packages/core/dist/consultation/tandem-metrics.test.d.ts +18 -0
- package/packages/core/dist/consultation/tandem-metrics.test.d.ts.map +1 -0
- package/packages/core/dist/consultation/tandem-metrics.test.js +457 -0
- package/packages/core/dist/consultation/tandem-metrics.test.js.map +1 -0
- package/packages/core/dist/public/js/react/react.js +14 -14
- 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/server/api/agent-load.js +1 -1
- package/packages/core/dist/server/api/agent-load.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
- package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
- package/packages/core/dist/server/otlp-receiver.js +185 -24
- package/packages/core/dist/server/otlp-receiver.js.map +1 -1
- package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
- package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
- package/packages/core/dist/server/otlp-receiver.test.js +446 -0
- package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
- package/packages/core/dist/server/server.d.ts +0 -3
- package/packages/core/dist/server/server.d.ts.map +1 -1
- package/packages/core/dist/server/server.js +3 -37
- package/packages/core/dist/server/server.js.map +1 -1
- package/packages/core/dist/server/server.test.d.ts +1 -1
- package/packages/core/dist/server/server.test.js +12 -23
- package/packages/core/dist/server/server.test.js.map +1 -1
- package/packages/core/dist/shared/capabilities.d.ts +88 -0
- package/packages/core/dist/shared/capabilities.d.ts.map +1 -0
- package/packages/core/dist/shared/capabilities.js +133 -0
- package/packages/core/dist/shared/capabilities.js.map +1 -0
- package/packages/core/dist/shared/capabilities.test.d.ts +2 -0
- package/packages/core/dist/shared/capabilities.test.d.ts.map +1 -0
- package/packages/core/dist/shared/capabilities.test.js +217 -0
- package/packages/core/dist/shared/capabilities.test.js.map +1 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
- package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
- package/packages/core/dist/shared/portrait-resolver.js +27 -0
- package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
- package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
- package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
- package/packages/core/dist/shared/spawn-prompt.d.ts +47 -0
- package/packages/core/dist/shared/spawn-prompt.d.ts.map +1 -0
- package/packages/core/dist/shared/spawn-prompt.js +82 -0
- package/packages/core/dist/shared/spawn-prompt.js.map +1 -0
- package/packages/core/dist/shared/spawn-prompt.test.d.ts +2 -0
- package/packages/core/dist/shared/spawn-prompt.test.d.ts.map +1 -0
- package/packages/core/dist/shared/spawn-prompt.test.js +251 -0
- package/packages/core/dist/shared/spawn-prompt.test.js.map +1 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
- package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
- package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts +18 -0
- package/packages/core/dist/workflow/tandem-workflow-templates.test.d.ts.map +1 -0
- package/packages/core/dist/workflow/tandem-workflow-templates.test.js +434 -0
- package/packages/core/dist/workflow/tandem-workflow-templates.test.js.map +1 -0
- package/packages/core/dist/workflow/workflow-schema.d.ts +32 -0
- package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
- package/packages/core/dist/workflow/workflow-schema.js +120 -0
- package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
- package/packages/core/dist/workflow/workflow-schema.test.d.ts.map +1 -1
- package/packages/core/dist/workflow/workflow-schema.test.js +570 -1
- package/packages/core/dist/workflow/workflow-schema.test.js.map +1 -1
- package/pennyfarthing-dist/agents/dev.md +7 -11
- package/pennyfarthing-dist/agents/reviewer.md +9 -3
- package/pennyfarthing-dist/agents/sm-finish.md +18 -1
- package/pennyfarthing-dist/agents/sm-setup.md +1 -1
- package/pennyfarthing-dist/agents/sm.md +2 -2
- package/pennyfarthing-dist/agents/tea.md +1 -1
- package/pennyfarthing-dist/agents/testing-runner.md +2 -1
- package/pennyfarthing-dist/commands/pf-chore.md +2 -2
- package/pennyfarthing-dist/commands/pf-git.md +4 -2
- package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
- package/pennyfarthing-dist/gates/approval.md +63 -0
- package/pennyfarthing-dist/gates/confidence-sm.md +71 -0
- package/pennyfarthing-dist/gates/context-ok.md +56 -0
- package/pennyfarthing-dist/gates/evaluations/confidence-sm.md +54 -0
- package/pennyfarthing-dist/gates/quality-pass.md +67 -0
- package/pennyfarthing-dist/gates/tests-fail.md +84 -0
- package/pennyfarthing-dist/gates/tests-pass.md +79 -0
- package/pennyfarthing-dist/guides/agent-behavior.md +23 -19
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
- package/pennyfarthing-dist/guides/bell-mode.md +1 -1
- package/pennyfarthing-dist/guides/bikerack.md +3 -3
- package/pennyfarthing-dist/guides/hooks.md +29 -29
- package/pennyfarthing-dist/guides/reflector.md +1 -1
- package/pennyfarthing-dist/guides/tandem-protocol.md +3 -3
- package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
- package/pennyfarthing-dist/guides/xml-tags.md +2 -2
- package/pennyfarthing-dist/scripts/README.md +1 -1
- package/pennyfarthing-dist/scripts/core/check-context.sh +3 -1
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +5 -87
- package/pennyfarthing-dist/scripts/git/README.md +24 -14
- package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
- package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
- package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
- package/pennyfarthing-dist/scripts/hooks/README.md +6 -6
- package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +4 -183
- package/pennyfarthing-dist/scripts/hooks/context-circuit-breaker.sh +4 -95
- package/pennyfarthing-dist/scripts/hooks/context-warning.sh +4 -65
- package/pennyfarthing-dist/scripts/hooks/cyclist-pretooluse-hook.sh +3 -31
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +27 -33
- package/pennyfarthing-dist/scripts/hooks/pre-edit-check.sh +4 -71
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +3 -19
- package/pennyfarthing-dist/scripts/hooks/schema-validation.sh +4 -30
- package/pennyfarthing-dist/scripts/hooks/session-start.sh +3 -32
- package/pennyfarthing-dist/scripts/hooks/session-stop.sh +4 -65
- package/pennyfarthing-dist/scripts/hooks/sprint-yaml-validation.sh +4 -78
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +4 -93
- package/pennyfarthing-dist/scripts/misc/README.md +1 -1
- package/pennyfarthing-dist/scripts/misc/statusline.sh +4 -301
- package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
- package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
- package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
- package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
- package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
- package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
- package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
- package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
- package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
- package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
- package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
- package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
- package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
- package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
- package/pennyfarthing-dist/templates/settings.local.json.template +19 -10
- package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
- package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
- package/pennyfarthing-dist/workflows/tdd.yaml +11 -2
- package/pennyfarthing_scripts/CLAUDE.md +45 -14
- 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-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/config.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/cli.py +3 -5
- package/pennyfarthing_scripts/bellmode_hook.py +12 -296
- 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-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-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/audit_log_panel.py +119 -0
- package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
- package/pennyfarthing_scripts/bikerack/base_panel.py +87 -2
- package/pennyfarthing_scripts/bikerack/changed_panel.py +125 -29
- package/pennyfarthing_scripts/bikerack/context_meter_footer.py +88 -0
- package/pennyfarthing_scripts/bikerack/debug_panel.py +32 -2
- package/pennyfarthing_scripts/bikerack/diffs_panel.py +104 -17
- package/pennyfarthing_scripts/bikerack/events.py +28 -0
- package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
- package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
- package/pennyfarthing_scripts/bikerack/portrait_resolver.py +139 -0
- package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
- package/pennyfarthing_scripts/bikerack/sprint_panel.py +395 -32
- package/pennyfarthing_scripts/bikerack/story_detail_data.py +244 -0
- package/pennyfarthing_scripts/bikerack/story_detail_screen.py +176 -0
- package/pennyfarthing_scripts/bikerack/tui.py +575 -37
- package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
- 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 +42 -65
- 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-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/pr_config.py +38 -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/__init__.py +1 -0
- package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.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/consultation/cli.py +149 -0
- package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
- package/pennyfarthing_scripts/context.py +3 -3
- 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-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-314.pyc +0 -0
- package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__init__.py +12 -1
- 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 +3 -4
- package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
- package/pennyfarthing_scripts/git/repos.py +196 -0
- package/pennyfarthing_scripts/git/status_all.py +27 -11
- package/pennyfarthing_scripts/git/worktree.py +302 -0
- package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/cli.py +143 -40
- package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.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__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/cli.py +33 -1
- package/pennyfarthing_scripts/handoff/complete_phase.py +40 -0
- package/pennyfarthing_scripts/handoff/marker.py +15 -15
- package/pennyfarthing_scripts/handoff/phase_check.py +96 -0
- package/pennyfarthing_scripts/handoff/resolve_gate.py +18 -15
- 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-314.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-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__init__.py +437 -0
- package/pennyfarthing_scripts/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/bell_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_breaker.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/context_warning.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/cyclist_pretooluse.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/pre_edit_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/schema_validation.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/__pycache__/statusline.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hooks/bell_mode.py +215 -0
- package/pennyfarthing_scripts/hooks/cli.py +96 -0
- package/pennyfarthing_scripts/hooks/context_breaker.py +104 -0
- package/pennyfarthing_scripts/hooks/context_warning.py +66 -0
- package/pennyfarthing_scripts/hooks/cyclist_pretooluse.py +129 -0
- package/pennyfarthing_scripts/hooks/pre_edit_check.py +78 -0
- package/pennyfarthing_scripts/hooks/reflector_check.py +271 -0
- package/pennyfarthing_scripts/hooks/schema_validation.py +203 -0
- package/pennyfarthing_scripts/hooks/session_start.py +296 -0
- package/pennyfarthing_scripts/hooks/session_stop.py +111 -0
- package/pennyfarthing_scripts/hooks/sprint_yaml_validation.py +97 -0
- package/pennyfarthing_scripts/hooks/statusline.py +420 -0
- package/pennyfarthing_scripts/hooks.py +27 -446
- 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/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/launch/__pycache__/__init__.cpython-314.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/pretooluse_hook.py +3 -185
- 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/prime/heatmap.py +655 -0
- package/pennyfarthing_scripts/prime/workflow.py +2 -1
- package/pennyfarthing_scripts/schema_validation_hook.py +3 -298
- package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/session_start_hook.py +4 -186
- 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__/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-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_finish.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/loader.py +15 -1
- package/pennyfarthing_scripts/sprint/story_update.py +19 -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_bikerack.py +51 -51
- package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
- package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
- package/pennyfarthing_scripts/tests/test_sprint_panel.py +344 -265
- package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
- package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.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/validate/adapters/tandem_awareness.py +254 -0
- package/pennyfarthing_scripts/validate/adapters/workflow.py +19 -0
- package/pennyfarthing_scripts/validate/cli.py +17 -5
- package/pennyfarthing_scripts/welcome_hook.py +3 -149
- package/pennyfarthing_scripts/workflow/__init__.py +40 -0
- package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.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-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/workflow/cli.py +1100 -0
- package/pennyfarthing_scripts/workflow/helpers.py +241 -0
- package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
- package/pennyfarthing_scripts/workflow/state.py +112 -0
- package/pennyfarthing_scripts/workflow/team_lifecycle.py +257 -0
- package/packages/core/dist/scripts/theme-detail.test.d.ts +0 -10
- package/packages/core/dist/scripts/theme-detail.test.js +0 -199
- package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
- package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
- package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
- package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
- package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
- 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/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
|
@@ -5,15 +5,16 @@ Usage:
|
|
|
5
5
|
pf git [COMMAND] [ARGS]...
|
|
6
6
|
|
|
7
7
|
Commands:
|
|
8
|
-
status
|
|
9
|
-
cleanup
|
|
10
|
-
branches
|
|
11
|
-
|
|
8
|
+
status Check git status of all project repos
|
|
9
|
+
cleanup Organize changes into proper commits/branches
|
|
10
|
+
branches Create feature branches from a story
|
|
11
|
+
worktree Manage git worktrees for parallel work
|
|
12
|
+
install-hooks Install git hooks with .d/ dispatcher pattern
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
|
-
import
|
|
15
|
+
import asyncio
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
import click
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@click.group()
|
|
@@ -22,10 +23,11 @@ def git():
|
|
|
22
23
|
|
|
23
24
|
\b
|
|
24
25
|
Commands:
|
|
25
|
-
status
|
|
26
|
-
cleanup
|
|
27
|
-
branches
|
|
28
|
-
|
|
26
|
+
status - Check git status of all repos
|
|
27
|
+
cleanup - Organize changes into commits/branches
|
|
28
|
+
branches - Create feature branches from a story
|
|
29
|
+
worktree - Manage git worktrees for parallel work
|
|
30
|
+
install-hooks - Install git hooks with .d/ dispatcher
|
|
29
31
|
"""
|
|
30
32
|
pass
|
|
31
33
|
|
|
@@ -37,21 +39,38 @@ def status(brief: bool):
|
|
|
37
39
|
|
|
38
40
|
Shows branch, uncommitted changes, and ahead/behind status for each repo.
|
|
39
41
|
"""
|
|
40
|
-
import
|
|
42
|
+
from pennyfarthing_scripts.git.repos import get_repo_paths, load_repos_config
|
|
43
|
+
from pennyfarthing_scripts.git.status_all import (
|
|
44
|
+
format_status_brief,
|
|
45
|
+
format_status_full,
|
|
46
|
+
format_summary,
|
|
47
|
+
get_all_repo_status,
|
|
48
|
+
)
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
repo_paths = get_repo_paths()
|
|
51
|
+
config = load_repos_config()
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
# Build repo list with per-repo upstream refs
|
|
54
|
+
repos_with_upstream: list[tuple[str, object, str]] = []
|
|
55
|
+
for name, path in repo_paths:
|
|
56
|
+
upstream = config[name].upstream_ref if name in config else "origin/main"
|
|
57
|
+
repos_with_upstream.append((name, path, upstream))
|
|
58
|
+
|
|
59
|
+
statuses = asyncio.run(get_all_repo_status(repos_with_upstream))
|
|
48
60
|
|
|
49
|
-
cmd = [str(script)]
|
|
50
61
|
if brief:
|
|
51
|
-
|
|
62
|
+
click.echo(format_status_brief(statuses))
|
|
63
|
+
else:
|
|
64
|
+
click.echo("━" * 40)
|
|
65
|
+
click.echo(" Git Status - All Repos")
|
|
66
|
+
click.echo("━" * 40)
|
|
67
|
+
click.echo()
|
|
68
|
+
click.echo(format_status_full(statuses))
|
|
69
|
+
click.echo("━" * 40)
|
|
70
|
+
click.echo(format_summary(statuses))
|
|
52
71
|
|
|
53
|
-
|
|
54
|
-
raise SystemExit(
|
|
72
|
+
has_issues = any(not s.is_clean or s.has_unpushed for s in statuses)
|
|
73
|
+
raise SystemExit(1 if has_issues else 0)
|
|
55
74
|
|
|
56
75
|
|
|
57
76
|
@git.command()
|
|
@@ -67,34 +86,118 @@ def cleanup():
|
|
|
67
86
|
|
|
68
87
|
|
|
69
88
|
@git.command()
|
|
70
|
-
@click.argument("
|
|
71
|
-
|
|
72
|
-
""
|
|
89
|
+
@click.argument("branch_name")
|
|
90
|
+
@click.option(
|
|
91
|
+
"--repos",
|
|
92
|
+
type=click.Choice(["all", "api", "ui"]),
|
|
93
|
+
default="all",
|
|
94
|
+
help="Which repos to target",
|
|
95
|
+
)
|
|
96
|
+
def branches(branch_name: str, repos: str):
|
|
97
|
+
"""Create feature branches across all configured repos.
|
|
73
98
|
|
|
74
99
|
\b
|
|
75
100
|
Arguments:
|
|
76
|
-
|
|
101
|
+
BRANCH_NAME - The branch name to create (e.g., feat/86-3-file-upload)
|
|
77
102
|
"""
|
|
78
|
-
import
|
|
103
|
+
from pennyfarthing_scripts.git.create_branches import (
|
|
104
|
+
create_feature_branches,
|
|
105
|
+
detect_worktree,
|
|
106
|
+
filter_repos,
|
|
107
|
+
format_results,
|
|
108
|
+
)
|
|
109
|
+
from pennyfarthing_scripts.git.repos import get_repo_paths
|
|
110
|
+
|
|
111
|
+
is_worktree, worktree_name, _ = detect_worktree()
|
|
112
|
+
if is_worktree:
|
|
113
|
+
click.echo(f"📂 Detected worktree: {worktree_name}")
|
|
114
|
+
else:
|
|
115
|
+
click.echo("📂 Using main checkout")
|
|
116
|
+
|
|
117
|
+
all_repos = get_repo_paths()
|
|
118
|
+
filtered = filter_repos(all_repos, repos)
|
|
119
|
+
|
|
120
|
+
if not filtered:
|
|
121
|
+
click.echo(f"No repos match filter: {repos}", err=True)
|
|
122
|
+
raise SystemExit(1)
|
|
79
123
|
|
|
80
|
-
|
|
81
|
-
|
|
124
|
+
results = asyncio.run(create_feature_branches(filtered, branch_name))
|
|
125
|
+
click.echo(format_results(results, branch_name))
|
|
82
126
|
|
|
83
|
-
|
|
84
|
-
click.echo("Error: create-branches.sh not found", err=True)
|
|
85
|
-
raise SystemExit(1)
|
|
127
|
+
from pennyfarthing_scripts.git.create_branches import BranchAction
|
|
86
128
|
|
|
87
|
-
|
|
88
|
-
raise SystemExit(
|
|
129
|
+
has_errors = any(r.action == BranchAction.ERROR for r in results)
|
|
130
|
+
raise SystemExit(1 if has_errors else 0)
|
|
89
131
|
|
|
90
132
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
133
|
+
# Worktree subgroup
|
|
134
|
+
@git.group()
|
|
135
|
+
def worktree():
|
|
136
|
+
"""Manage git worktrees for parallel development.
|
|
137
|
+
|
|
138
|
+
\b
|
|
139
|
+
Commands:
|
|
140
|
+
create - Create worktree(s) for parallel work
|
|
141
|
+
remove - Remove worktree and clean up
|
|
142
|
+
list - List all active worktrees
|
|
143
|
+
status - Show detailed worktree status
|
|
144
|
+
"""
|
|
145
|
+
pass
|
|
94
146
|
|
|
95
|
-
|
|
96
|
-
|
|
147
|
+
|
|
148
|
+
@worktree.command("create")
|
|
149
|
+
@click.argument("name")
|
|
150
|
+
@click.argument("branch")
|
|
151
|
+
@click.option(
|
|
152
|
+
"--repos",
|
|
153
|
+
default="all",
|
|
154
|
+
help="Repos filter: all, api, ui, or comma-separated names",
|
|
155
|
+
)
|
|
156
|
+
def worktree_create(name: str, branch: str, repos: str):
|
|
157
|
+
"""Create worktree(s) for parallel work.
|
|
158
|
+
|
|
159
|
+
\b
|
|
160
|
+
Arguments:
|
|
161
|
+
NAME - Worktree name (e.g., wt-5-3a)
|
|
162
|
+
BRANCH - Branch name (e.g., feat/5-3a-file-upload)
|
|
97
163
|
"""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
164
|
+
from pennyfarthing_scripts.git.worktree import create_worktree
|
|
165
|
+
|
|
166
|
+
raise SystemExit(create_worktree(name, branch, repos))
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@worktree.command("remove")
|
|
170
|
+
@click.argument("name")
|
|
171
|
+
def worktree_remove(name: str):
|
|
172
|
+
"""Remove worktree and clean up."""
|
|
173
|
+
from pennyfarthing_scripts.git.worktree import remove_worktree
|
|
174
|
+
|
|
175
|
+
raise SystemExit(remove_worktree(name))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@worktree.command("list")
|
|
179
|
+
def worktree_list():
|
|
180
|
+
"""List all active worktrees."""
|
|
181
|
+
from pennyfarthing_scripts.git.worktree import list_worktrees
|
|
182
|
+
|
|
183
|
+
raise SystemExit(list_worktrees())
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@worktree.command("status")
|
|
187
|
+
def worktree_status():
|
|
188
|
+
"""Show detailed worktree status."""
|
|
189
|
+
from pennyfarthing_scripts.git.worktree import show_worktree_status
|
|
190
|
+
|
|
191
|
+
raise SystemExit(show_worktree_status())
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@git.command("install-hooks")
|
|
195
|
+
def install_hooks():
|
|
196
|
+
"""Install git hooks with .d/ dispatcher pattern.
|
|
197
|
+
|
|
198
|
+
Creates .d/ directories, symlinks pennyfarthing hooks, and
|
|
199
|
+
migrates existing user hooks.
|
|
200
|
+
"""
|
|
201
|
+
from pennyfarthing_scripts.git.hooks_installer import install_git_hooks
|
|
202
|
+
|
|
203
|
+
raise SystemExit(install_git_hooks())
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -4,8 +4,9 @@ Usage:
|
|
|
4
4
|
pf handoff resolve-gate STORY_ID WORKFLOW PHASE
|
|
5
5
|
pf handoff complete-phase STORY_ID WORKFLOW FROM_PHASE TO_PHASE GATE_TYPE
|
|
6
6
|
pf handoff marker NEXT_AGENT [--error MESSAGE]
|
|
7
|
+
pf handoff phase-check AGENT
|
|
7
8
|
|
|
8
|
-
Stories: 105-1, 105-4 (Script-First Handoff)
|
|
9
|
+
Stories: 105-1, 105-4 (Script-First Handoff), 110-8 (CLI Relay Handoff Fix)
|
|
9
10
|
"""
|
|
10
11
|
|
|
11
12
|
from __future__ import annotations
|
|
@@ -22,6 +23,7 @@ def handoff():
|
|
|
22
23
|
resolve-gate - Resolve gate for current phase
|
|
23
24
|
complete-phase - Complete phase transition atomically
|
|
24
25
|
marker - Generate AGENT_COMMAND handoff marker
|
|
26
|
+
phase-check - Check if agent owns current phase
|
|
25
27
|
"""
|
|
26
28
|
pass
|
|
27
29
|
|
|
@@ -118,3 +120,33 @@ def marker_cmd(next_agent: str | None, error_msg: str | None):
|
|
|
118
120
|
)
|
|
119
121
|
|
|
120
122
|
click.echo(generate_marker(next_agent, error=error_msg))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@handoff.command("phase-check")
|
|
126
|
+
@click.argument("agent")
|
|
127
|
+
def phase_check_cmd(agent: str):
|
|
128
|
+
"""Check if the requested agent owns the current workflow phase.
|
|
129
|
+
|
|
130
|
+
Returns a YAML block with action ("start" or "redirect"), the correct
|
|
131
|
+
agent, story ID, phase, and a human-readable message.
|
|
132
|
+
|
|
133
|
+
If the agent does not own the phase, generates a handoff marker for
|
|
134
|
+
the correct agent.
|
|
135
|
+
|
|
136
|
+
\b
|
|
137
|
+
Arguments:
|
|
138
|
+
AGENT - Agent to check (e.g., dev, tea, reviewer, sm)
|
|
139
|
+
"""
|
|
140
|
+
from pennyfarthing_scripts.handoff.phase_check import phase_check_start
|
|
141
|
+
|
|
142
|
+
result = phase_check_start(agent)
|
|
143
|
+
|
|
144
|
+
import yaml
|
|
145
|
+
|
|
146
|
+
click.echo(yaml.dump({"PHASE_CHECK": result}, default_flow_style=False).rstrip())
|
|
147
|
+
|
|
148
|
+
if result["action"] == "redirect":
|
|
149
|
+
click.echo("")
|
|
150
|
+
from pennyfarthing_scripts.handoff.marker import generate_marker
|
|
151
|
+
|
|
152
|
+
click.echo(generate_marker(result["agent"]))
|
|
@@ -53,11 +53,36 @@ def complete_phase(
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
content = session_path.read_text()
|
|
56
|
+
|
|
57
|
+
# Guard: require assessment section before allowing gated phase transitions.
|
|
58
|
+
# Skip/manual transitions (e.g. setup→implement) don't need assessments.
|
|
59
|
+
if gate_type not in ("skip", "manual", "-", None, "") and not re.search(
|
|
60
|
+
r"^##\s+.*Assessment", content, re.MULTILINE
|
|
61
|
+
):
|
|
62
|
+
return {
|
|
63
|
+
"status": "error",
|
|
64
|
+
"session_file": str(session_path),
|
|
65
|
+
"error": "No assessment found in session file. Write your assessment before completing the phase.",
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
57
69
|
|
|
58
70
|
from_agent = _get_phase_agent(project_root, workflow, from_phase)
|
|
59
71
|
to_agent = _get_phase_agent(project_root, workflow, to_phase)
|
|
60
72
|
|
|
73
|
+
# Update tandem line: remove existing, add if to_phase has tandem config
|
|
74
|
+
content = re.sub(r"\*\*Tandem:\*\*[^\n]*\n", "", content)
|
|
75
|
+
tandem = _get_phase_tandem(project_root, workflow, to_phase)
|
|
76
|
+
if tandem:
|
|
77
|
+
partner = tandem["partner"]
|
|
78
|
+
scope = tandem["scope"]
|
|
79
|
+
tandem_line = f"**Tandem:** {partner} ({scope})\n"
|
|
80
|
+
content = re.sub(
|
|
81
|
+
r"(\*\*Workflow:\*\*[^\n]*\n)",
|
|
82
|
+
rf"\1{tandem_line}",
|
|
83
|
+
content,
|
|
84
|
+
)
|
|
85
|
+
|
|
61
86
|
# Update all **Phase:** lines to new phase
|
|
62
87
|
content = re.sub(r"(\*\*Phase:\*\*) \S+", rf"\1 {to_phase}", content)
|
|
63
88
|
|
|
@@ -133,6 +158,21 @@ def _calc_duration(started_str: str, ended_str: str) -> str:
|
|
|
133
158
|
return f"{hours}h {rem_minutes}m" if rem_minutes else f"{hours}h"
|
|
134
159
|
|
|
135
160
|
|
|
161
|
+
def _get_phase_tandem(project_root: Path, workflow: str, phase: str) -> dict | None:
|
|
162
|
+
"""Return tandem config for a phase, or None if no tandem block."""
|
|
163
|
+
for name in [f"{workflow}.yaml", f"{workflow}/workflow.yaml"]:
|
|
164
|
+
path = project_root / ".pennyfarthing" / "workflows" / name
|
|
165
|
+
if path.exists():
|
|
166
|
+
try:
|
|
167
|
+
data = yaml.safe_load(path.read_text())
|
|
168
|
+
for p in data["workflow"]["phases"]:
|
|
169
|
+
if p["name"] == phase:
|
|
170
|
+
return p.get("tandem")
|
|
171
|
+
except Exception:
|
|
172
|
+
pass
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
|
|
136
176
|
def _get_phase_agent(project_root: Path, workflow: str, phase: str) -> str:
|
|
137
177
|
for name in [f"{workflow}.yaml", f"{workflow}/workflow.yaml"]:
|
|
138
178
|
path = project_root / ".pennyfarthing" / "workflows" / name
|
|
@@ -72,25 +72,25 @@ def generate_marker(
|
|
|
72
72
|
fallback=f"Run `{cmd}` to continue",
|
|
73
73
|
)
|
|
74
74
|
|
|
75
|
-
# Non-Cyclist relay:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
# Non-Cyclist relay: return structured action for the agent to act on.
|
|
76
|
+
# The calling agent reads the `action` field and executes accordingly.
|
|
77
|
+
if ctx.use_tirepump:
|
|
78
|
+
return _block(
|
|
79
|
+
action="tirepump_handoff",
|
|
80
|
+
next_agent=next_agent,
|
|
81
|
+
fallback=f"Context is high ({pct}%). Run /clear then {cmd}",
|
|
82
|
+
context_percent=pct,
|
|
83
|
+
relay_mode=True,
|
|
83
84
|
)
|
|
84
|
-
agent_output = result.stdout.strip()
|
|
85
|
-
except Exception as e:
|
|
86
|
-
agent_output = f"Failed to invoke agent: {e}"
|
|
87
85
|
|
|
88
86
|
return _block(
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
action="inline_handoff",
|
|
88
|
+
next_agent=next_agent,
|
|
89
|
+
activation_command=f"pf agent start {next_agent} --tier handoff --quiet",
|
|
90
|
+
fallback=f"Run `{cmd}` to continue",
|
|
91
91
|
context_percent=pct,
|
|
92
|
-
|
|
93
|
-
)
|
|
92
|
+
relay_mode=True,
|
|
93
|
+
)
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
def _block(**fields: object) -> str:
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Phase check for agent activation.
|
|
2
|
+
|
|
3
|
+
Determines whether the requested agent owns the current workflow phase.
|
|
4
|
+
If not, returns a redirect to the correct agent. Replaces phase-check-start.sh.
|
|
5
|
+
|
|
6
|
+
Story: 110-8 (CLI Relay Handoff Fix)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from pennyfarthing_scripts.common.config import get_project_root
|
|
14
|
+
from pennyfarthing_scripts.prime.workflow import (
|
|
15
|
+
check_redirect,
|
|
16
|
+
detect_workflow_state,
|
|
17
|
+
find_active_session,
|
|
18
|
+
parse_session_header,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def phase_check_start(
|
|
23
|
+
agent_name: str,
|
|
24
|
+
project_root: Path | None = None,
|
|
25
|
+
) -> dict:
|
|
26
|
+
"""Check if requested agent owns current phase.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
agent_name: Agent to check (e.g., "dev", "tea", "reviewer").
|
|
30
|
+
project_root: Project root path (auto-detected if not provided).
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Dict with:
|
|
34
|
+
action: "start" (proceed) or "redirect" (wrong agent)
|
|
35
|
+
agent: The agent that should run
|
|
36
|
+
story_id: Current story ID (if session exists)
|
|
37
|
+
phase: Current phase (if session exists)
|
|
38
|
+
phase_owner: Agent that owns the phase
|
|
39
|
+
message: Human-readable explanation
|
|
40
|
+
"""
|
|
41
|
+
root = project_root or get_project_root()
|
|
42
|
+
|
|
43
|
+
# Find active session
|
|
44
|
+
session_file = find_active_session(root)
|
|
45
|
+
if not session_file:
|
|
46
|
+
return {
|
|
47
|
+
"action": "start",
|
|
48
|
+
"agent": agent_name,
|
|
49
|
+
"story_id": None,
|
|
50
|
+
"phase": None,
|
|
51
|
+
"phase_owner": None,
|
|
52
|
+
"message": f"No active session — starting {agent_name}",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Parse session header
|
|
56
|
+
header = parse_session_header(session_file)
|
|
57
|
+
story_id = header.get("story_id")
|
|
58
|
+
workflow = header.get("workflow", "tdd")
|
|
59
|
+
phase = header.get("phase")
|
|
60
|
+
|
|
61
|
+
if not phase:
|
|
62
|
+
return {
|
|
63
|
+
"action": "start",
|
|
64
|
+
"agent": agent_name,
|
|
65
|
+
"story_id": story_id,
|
|
66
|
+
"phase": None,
|
|
67
|
+
"phase_owner": None,
|
|
68
|
+
"message": f"No phase detected — starting {agent_name}",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Use detect_workflow_state + check_redirect for consistent logic
|
|
72
|
+
workflow_status = detect_workflow_state(root)
|
|
73
|
+
redirect = check_redirect(workflow_status, agent_name)
|
|
74
|
+
|
|
75
|
+
if redirect:
|
|
76
|
+
target_agent, reason = redirect
|
|
77
|
+
return {
|
|
78
|
+
"action": "redirect",
|
|
79
|
+
"agent": target_agent,
|
|
80
|
+
"story_id": story_id,
|
|
81
|
+
"phase": phase,
|
|
82
|
+
"phase_owner": target_agent,
|
|
83
|
+
"message": (
|
|
84
|
+
f"Story {story_id} is in '{phase}' phase "
|
|
85
|
+
f"(workflow: {workflow}) — owned by {target_agent}"
|
|
86
|
+
),
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
"action": "start",
|
|
91
|
+
"agent": agent_name,
|
|
92
|
+
"story_id": story_id,
|
|
93
|
+
"phase": phase,
|
|
94
|
+
"phase_owner": agent_name,
|
|
95
|
+
"message": f"Agent {agent_name} owns phase '{phase}' — proceeding",
|
|
96
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""Resolve gate for current workflow phase.
|
|
2
2
|
|
|
3
|
-
Reads workflow YAML, finds current phase gate,
|
|
4
|
-
|
|
3
|
+
Reads workflow YAML, finds current phase gate, and returns gate info.
|
|
4
|
+
Assessment checks are enforced in complete_phase (not here) to avoid
|
|
5
|
+
race conditions where agents call resolve-gate before writing assessments.
|
|
5
6
|
|
|
6
7
|
Story: 105-1 (Script-First Handoff)
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
10
|
from __future__ import annotations
|
|
10
11
|
|
|
11
|
-
import re
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
import yaml
|
|
@@ -67,7 +67,19 @@ def resolve_gate(
|
|
|
67
67
|
|
|
68
68
|
gate = current_phase.get("gate")
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
# Support explicit next: directive for non-linear phase routing
|
|
71
|
+
explicit_next = current_phase.get("next")
|
|
72
|
+
if explicit_next:
|
|
73
|
+
nxt = next((p for p in phases if p["name"] == explicit_next), None)
|
|
74
|
+
if nxt:
|
|
75
|
+
next_phase = nxt["name"]
|
|
76
|
+
next_agent = nxt["agent"]
|
|
77
|
+
else:
|
|
78
|
+
return _result(
|
|
79
|
+
status="error",
|
|
80
|
+
error=f"Phase '{explicit_next}' referenced by next: not found in workflow '{workflow}'",
|
|
81
|
+
)
|
|
82
|
+
elif current_idx + 1 < len(phases):
|
|
71
83
|
nxt = phases[current_idx + 1]
|
|
72
84
|
next_phase = nxt["name"]
|
|
73
85
|
next_agent = nxt["agent"]
|
|
@@ -95,22 +107,13 @@ def resolve_gate(
|
|
|
95
107
|
assessment_found=True,
|
|
96
108
|
)
|
|
97
109
|
|
|
98
|
-
session_path = project_root / ".session" / f"{story_id}-session.md"
|
|
99
|
-
assessment_found = False
|
|
100
|
-
if session_path.exists():
|
|
101
|
-
content = session_path.read_text()
|
|
102
|
-
assessment_found = bool(
|
|
103
|
-
re.search(r"^##\s+.*Assessment", content, re.MULTILINE)
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
status = "ready" if assessment_found else "blocked"
|
|
107
110
|
return _result(
|
|
108
|
-
status=
|
|
111
|
+
status="ready",
|
|
109
112
|
gate_type=gate_type,
|
|
110
113
|
gate_file=gate_file,
|
|
111
114
|
next_agent=next_agent,
|
|
112
115
|
next_phase=next_phase,
|
|
113
|
-
assessment_found=
|
|
116
|
+
assessment_found=True,
|
|
114
117
|
)
|
|
115
118
|
|
|
116
119
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|