@pennyfarthing/core 11.1.1 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +8 -8
  2. package/package.json +1 -1
  3. package/packages/core/dist/server/otlp-receiver.d.ts +16 -11
  4. package/packages/core/dist/server/otlp-receiver.d.ts.map +1 -1
  5. package/packages/core/dist/server/otlp-receiver.js +185 -24
  6. package/packages/core/dist/server/otlp-receiver.js.map +1 -1
  7. package/packages/core/dist/server/otlp-receiver.test.d.ts +21 -0
  8. package/packages/core/dist/server/otlp-receiver.test.d.ts.map +1 -0
  9. package/packages/core/dist/server/otlp-receiver.test.js +446 -0
  10. package/packages/core/dist/server/otlp-receiver.test.js.map +1 -0
  11. package/packages/core/dist/shared/portrait-resolver.d.ts +9 -0
  12. package/packages/core/dist/shared/portrait-resolver.d.ts.map +1 -1
  13. package/packages/core/dist/shared/portrait-resolver.js +27 -0
  14. package/packages/core/dist/shared/portrait-resolver.js.map +1 -1
  15. package/packages/core/dist/shared/portrait-resolver.test.js +47 -1
  16. package/packages/core/dist/shared/portrait-resolver.test.js.map +1 -1
  17. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts +13 -0
  18. package/packages/core/dist/shared/tandem-portrait-inventory.test.d.ts.map +1 -0
  19. package/packages/core/dist/shared/tandem-portrait-inventory.test.js +126 -0
  20. package/packages/core/dist/shared/tandem-portrait-inventory.test.js.map +1 -0
  21. package/pennyfarthing-dist/agents/dev.md +1 -1
  22. package/pennyfarthing-dist/agents/reviewer.md +1 -1
  23. package/pennyfarthing-dist/agents/sm-setup.md +1 -1
  24. package/pennyfarthing-dist/agents/sm.md +2 -2
  25. package/pennyfarthing-dist/agents/tea.md +1 -1
  26. package/pennyfarthing-dist/agents/testing-runner.md +2 -1
  27. package/pennyfarthing-dist/commands/pf-chore.md +2 -2
  28. package/pennyfarthing-dist/commands/pf-standalone.md +7 -2
  29. package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
  30. package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
  31. package/pennyfarthing-dist/guides/bikerack.md +3 -3
  32. package/pennyfarthing-dist/guides/hooks.md +1 -1
  33. package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
  34. package/pennyfarthing-dist/guides/xml-tags.md +2 -2
  35. package/pennyfarthing-dist/scripts/README.md +1 -1
  36. package/pennyfarthing-dist/scripts/core/check-context.sh +1 -1
  37. package/pennyfarthing-dist/scripts/git/README.md +24 -14
  38. package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +5 -266
  39. package/pennyfarthing-dist/scripts/git/git-status-all.sh +5 -151
  40. package/pennyfarthing-dist/scripts/git/install-git-hooks.sh +6 -144
  41. package/pennyfarthing-dist/scripts/git/worktree-manager.sh +5 -496
  42. package/pennyfarthing-dist/scripts/hooks/README.md +1 -1
  43. package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
  44. package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
  45. package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
  46. package/pennyfarthing-dist/scripts/portraits/generate-tandem-portraits.sh +76 -0
  47. package/pennyfarthing-dist/scripts/workflow/fix-session-phase.sh +4 -221
  48. package/pennyfarthing-dist/scripts/workflow/get-workflow-type.sh +5 -13
  49. package/pennyfarthing-dist/scripts/workflow/list-workflows.sh +4 -123
  50. package/pennyfarthing-dist/scripts/workflow/phase-owner.sh +4 -33
  51. package/pennyfarthing-dist/scripts/workflow/resume-workflow.sh +4 -156
  52. package/pennyfarthing-dist/scripts/workflow/show-workflow.sh +4 -131
  53. package/pennyfarthing-dist/scripts/workflow/start-workflow.sh +4 -249
  54. package/pennyfarthing-dist/scripts/workflow/workflow-status.sh +4 -160
  55. package/pennyfarthing-dist/skills/pf-bc/usage.md +1 -1
  56. package/pennyfarthing-dist/skills/pf-jira/examples.md +5 -2
  57. package/pennyfarthing-dist/skills/pf-workflow/examples.md +27 -16
  58. package/pennyfarthing-dist/skills/pf-workflow/skill.md +9 -12
  59. package/pennyfarthing-dist/skills/pf-workflow/usage.md +33 -8
  60. package/pennyfarthing-dist/workflows/bdd-tandem.yaml +18 -6
  61. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-01-analyze.md +1 -1
  62. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-04-verify.md +1 -1
  63. package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
  64. package/pennyfarthing-dist/workflows/review-tandem.yaml +65 -0
  65. package/pennyfarthing-dist/workflows/tdd-tandem.yaml +16 -8
  66. package/pennyfarthing_scripts/CLAUDE.md +26 -4
  67. package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
  68. package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
  69. package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
  70. package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
  71. package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
  72. package/pennyfarthing_scripts/bc/cli.py +3 -5
  73. package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
  74. package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
  75. package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
  76. package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
  77. package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
  78. package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
  79. package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
  80. package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
  81. package/pennyfarthing_scripts/bikerack/__pycache__/portrait.cpython-314.pyc +0 -0
  82. package/pennyfarthing_scripts/bikerack/__pycache__/progress_panel.cpython-314.pyc +0 -0
  83. package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
  84. package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
  85. package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
  86. package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
  87. package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
  88. package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
  89. package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
  90. package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
  91. package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
  92. package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
  93. package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
  94. package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
  95. package/pennyfarthing_scripts/bikerack/tui.py +336 -30
  96. package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
  97. package/pennyfarthing_scripts/cli.py +37 -65
  98. package/pennyfarthing_scripts/consultation/__init__.py +1 -0
  99. package/pennyfarthing_scripts/consultation/__pycache__/__init__.cpython-314.pyc +0 -0
  100. package/pennyfarthing_scripts/consultation/__pycache__/cli.cpython-314.pyc +0 -0
  101. package/pennyfarthing_scripts/consultation/cli.py +149 -0
  102. package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
  103. package/pennyfarthing_scripts/context.py +3 -3
  104. package/pennyfarthing_scripts/epic/__pycache__/__init__.cpython-314.pyc +0 -0
  105. package/pennyfarthing_scripts/epic/__pycache__/cli.cpython-314.pyc +0 -0
  106. package/pennyfarthing_scripts/git/__init__.py +12 -1
  107. package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
  108. package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
  109. package/pennyfarthing_scripts/git/__pycache__/hooks_installer.cpython-314.pyc +0 -0
  110. package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
  111. package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
  112. package/pennyfarthing_scripts/git/__pycache__/worktree.cpython-314.pyc +0 -0
  113. package/pennyfarthing_scripts/git/create_branches.py +3 -4
  114. package/pennyfarthing_scripts/git/hooks_installer.py +152 -0
  115. package/pennyfarthing_scripts/git/repos.py +196 -0
  116. package/pennyfarthing_scripts/git/status_all.py +27 -11
  117. package/pennyfarthing_scripts/git/worktree.py +302 -0
  118. package/pennyfarthing_scripts/git_group/__pycache__/__init__.cpython-314.pyc +0 -0
  119. package/pennyfarthing_scripts/git_group/__pycache__/cli.cpython-314.pyc +0 -0
  120. package/pennyfarthing_scripts/git_group/cli.py +143 -40
  121. package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
  122. package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
  123. package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
  124. package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
  125. package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
  126. package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
  127. package/pennyfarthing_scripts/hooks.py +3 -17
  128. package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
  129. package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
  130. package/pennyfarthing_scripts/prime/heatmap.py +655 -0
  131. package/pennyfarthing_scripts/session/__pycache__/__init__.cpython-314.pyc +0 -0
  132. package/pennyfarthing_scripts/session/__pycache__/cli.cpython-314.pyc +0 -0
  133. package/pennyfarthing_scripts/session_start_hook.py +1 -1
  134. package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
  135. package/pennyfarthing_scripts/sprint/loader.py +15 -1
  136. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
  137. package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
  138. package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
  139. package/pennyfarthing_scripts/tests/test_bikerack.py +51 -51
  140. package/pennyfarthing_scripts/tests/test_dialogue_manager.py +811 -0
  141. package/pennyfarthing_scripts/tests/test_handoff_cli.py +16 -11
  142. package/pennyfarthing_scripts/tests/test_workflow_check.py +2 -3
  143. package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
  144. package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
  145. package/pennyfarthing_scripts/validate/cli.py +17 -5
  146. package/pennyfarthing_scripts/workflow/__init__.py +40 -0
  147. package/pennyfarthing_scripts/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
  148. package/pennyfarthing_scripts/workflow/__pycache__/cli.cpython-314.pyc +0 -0
  149. package/pennyfarthing_scripts/workflow/__pycache__/helpers.cpython-314.pyc +0 -0
  150. package/pennyfarthing_scripts/workflow/__pycache__/scale.cpython-314.pyc +0 -0
  151. package/pennyfarthing_scripts/workflow/__pycache__/state.cpython-314.pyc +0 -0
  152. package/pennyfarthing_scripts/workflow/cli.py +1099 -0
  153. package/pennyfarthing_scripts/workflow/helpers.py +241 -0
  154. package/pennyfarthing_scripts/{workflow.py → workflow/scale.py} +0 -104
  155. package/pennyfarthing_scripts/workflow/state.py +112 -0
  156. package/pennyfarthing-dist/skills/pf-workflow/scripts/list-workflows.sh +0 -91
  157. package/pennyfarthing-dist/skills/pf-workflow/scripts/resume-workflow.sh +0 -163
  158. package/pennyfarthing-dist/skills/pf-workflow/scripts/show-workflow.sh +0 -138
  159. package/pennyfarthing-dist/skills/pf-workflow/scripts/start-workflow.sh +0 -273
  160. package/pennyfarthing-dist/skills/pf-workflow/scripts/workflow-status.sh +0 -167
@@ -1,222 +1,5 @@
1
1
  #!/bin/bash
2
- # Fix session file phase tracking when handoffs didn't update properly
3
- # Usage: fix-session-phase.sh <story-id> <target-phase> [--dry-run]
4
- #
5
- # Example: fix-session-phase.sh 56-1 review
6
- # fix-session-phase.sh MSSCI-12190 approved --dry-run
7
- #
8
- # This script detects the current phase, validates the target phase is reachable,
9
- # and updates the session file's Workflow Tracking section:
10
- # - Updates **Phase:** field to target phase
11
- # - Adds missing rows to Phase History table
12
- # - Adds missing rows to Handoff History table
13
- #
14
- # Valid phases for TDD workflow: setup → red → green → review → approved → finish
15
- # Valid phases for trivial workflow: setup → implement → review → approved → finish
16
-
17
- set -euo pipefail
18
-
19
- STORY_ID="${1:-}"
20
- TARGET_PHASE="${2:-}"
21
- DRY_RUN=false
22
-
23
- # Parse options
24
- for arg in "$@"; do
25
- case $arg in
26
- --dry-run)
27
- DRY_RUN=true
28
- ;;
29
- esac
30
- done
31
-
32
- if [[ -z "$STORY_ID" ]] || [[ -z "$TARGET_PHASE" ]]; then
33
- echo "Usage: fix-session-phase.sh <story-id> <target-phase> [--dry-run]"
34
- echo ""
35
- echo "Arguments:"
36
- echo " story-id Story ID (e.g., 56-1 or MSSCI-12190)"
37
- echo " target-phase Target phase to set (e.g., review, approved, finish)"
38
- echo ""
39
- echo "Options:"
40
- echo " --dry-run Show what would be done without executing"
41
- echo ""
42
- echo "Examples:"
43
- echo " fix-session-phase.sh 56-1 review # Update to review phase"
44
- echo " fix-session-phase.sh 56-1 approved # Update to approved phase"
45
- echo " fix-session-phase.sh 56-1 finish --dry-run # Preview finish update"
46
- exit 1
47
- fi
48
-
49
- # Find project root
50
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
51
-
52
- # Try multiple session file naming patterns
53
- SESSION_FILE=""
54
- STORY_ID_LOWER=$(echo "$STORY_ID" | tr '[:upper:]' '[:lower:]')
55
- for pattern in "${STORY_ID}-session.md" "${STORY_ID_LOWER}-session.md"; do
56
- if [[ -f "$PROJECT_ROOT/.session/$pattern" ]]; then
57
- SESSION_FILE="$PROJECT_ROOT/.session/$pattern"
58
- break
59
- fi
60
- done
61
-
62
- # Also try without the epic prefix (e.g., MSSCI-12190 might be in 56-1-session.md)
63
- if [[ -z "$SESSION_FILE" ]]; then
64
- # Search for session files containing this story ID
65
- found=$(grep -l "Jira:.*$STORY_ID\|ID:.*$STORY_ID" "$PROJECT_ROOT/.session/"*-session.md 2>/dev/null | head -1 || echo "")
66
- if [[ -n "$found" ]]; then
67
- SESSION_FILE="$found"
68
- fi
69
- fi
70
-
71
- if [[ -z "$SESSION_FILE" ]] || [[ ! -f "$SESSION_FILE" ]]; then
72
- echo "Error: Session file not found for story $STORY_ID"
73
- echo "Searched in: $PROJECT_ROOT/.session/"
74
- exit 1
75
- fi
76
-
77
- echo "Session file: $SESSION_FILE"
78
-
79
- # Extract current state
80
- CURRENT_PHASE=$(grep -E '^\*\*Phase:\*\*' "$SESSION_FILE" | sed 's/\*\*Phase:\*\* //' | tr -d ' ' || echo "unknown")
81
- WORKFLOW=$(grep -E '^\*\*Workflow:\*\*' "$SESSION_FILE" | head -1 | sed 's/\*\*Workflow:\*\* //' | tr -d ' ' || echo "tdd")
82
- PHASE_STARTED=$(grep -E '^\*\*Phase Started:\*\*' "$SESSION_FILE" | sed 's/\*\*Phase Started:\*\* //' | tr -d ' ' || echo "")
83
-
84
- echo "Current phase: $CURRENT_PHASE"
85
- echo "Target phase: $TARGET_PHASE"
86
- echo "Workflow: $WORKFLOW"
87
-
88
- # Define valid phase sequences
89
- case "$WORKFLOW" in
90
- tdd)
91
- PHASES=("setup" "red" "green" "review" "approved" "finish")
92
- AGENTS=("sm" "tea" "dev" "reviewer" "sm" "sm")
93
- GATES=("manual" "tests_fail" "tests_pass" "approval" "complete" "")
94
- ;;
95
- trivial)
96
- PHASES=("setup" "implement" "review" "approved" "finish")
97
- AGENTS=("sm" "dev" "reviewer" "sm" "sm")
98
- GATES=("manual" "tests_pass" "approval" "complete" "")
99
- ;;
100
- *)
101
- echo "Warning: Unknown workflow '$WORKFLOW', assuming TDD"
102
- PHASES=("setup" "red" "green" "review" "approved" "finish")
103
- AGENTS=("sm" "tea" "dev" "reviewer" "sm" "sm")
104
- GATES=("manual" "tests_fail" "tests_pass" "approval" "complete" "")
105
- ;;
106
- esac
107
-
108
- # Find indices
109
- CURRENT_IDX=-1
110
- TARGET_IDX=-1
111
- for i in "${!PHASES[@]}"; do
112
- if [[ "${PHASES[$i]}" == "$CURRENT_PHASE" ]]; then
113
- CURRENT_IDX=$i
114
- fi
115
- if [[ "${PHASES[$i]}" == "$TARGET_PHASE" ]]; then
116
- TARGET_IDX=$i
117
- fi
118
- done
119
-
120
- if [[ $CURRENT_IDX -eq -1 ]]; then
121
- echo "Error: Current phase '$CURRENT_PHASE' not found in $WORKFLOW workflow"
122
- echo "Valid phases: ${PHASES[*]}"
123
- exit 1
124
- fi
125
-
126
- if [[ $TARGET_IDX -eq -1 ]]; then
127
- echo "Error: Target phase '$TARGET_PHASE' not found in $WORKFLOW workflow"
128
- echo "Valid phases: ${PHASES[*]}"
129
- exit 1
130
- fi
131
-
132
- if [[ $TARGET_IDX -le $CURRENT_IDX ]]; then
133
- echo "Error: Target phase '$TARGET_PHASE' is not ahead of current phase '$CURRENT_PHASE'"
134
- echo "Phase sequence: ${PHASES[*]}"
135
- exit 1
136
- fi
137
-
138
- # Calculate what transitions are needed
139
- echo ""
140
- echo "Transitions needed:"
141
- NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
142
- TRANSITIONS=()
143
-
144
- for ((i=CURRENT_IDX; i<TARGET_IDX; i++)); do
145
- FROM_PHASE="${PHASES[$i]}"
146
- TO_PHASE="${PHASES[$((i+1))]}"
147
- FROM_AGENT="${AGENTS[$i]}"
148
- TO_AGENT="${AGENTS[$((i+1))]}"
149
- GATE="${GATES[$((i+1))]}"
150
-
151
- echo " $FROM_PHASE ($FROM_AGENT) → $TO_PHASE ($TO_AGENT) [gate: $GATE]"
152
- TRANSITIONS+=("$FROM_PHASE|$TO_PHASE|$FROM_AGENT|$TO_AGENT|$GATE")
153
- done
154
-
155
- if [[ "$DRY_RUN" == "true" ]]; then
156
- echo ""
157
- echo "[DRY RUN] Would update session file with:"
158
- echo " - **Phase:** $TARGET_PHASE"
159
- echo " - **Phase Started:** $NOW"
160
- echo " - Phase History: close out $CURRENT_PHASE, add intermediate phases"
161
- echo " - Handoff History: add ${#TRANSITIONS[@]} handoff(s)"
162
- exit 0
163
- fi
164
-
165
- echo ""
166
- echo "Updating session file..."
167
-
168
- # Build the Phase History additions
169
- PHASE_HISTORY_ADDITIONS=""
170
- HANDOFF_HISTORY_ADDITIONS=""
171
- PREV_END="$NOW"
172
-
173
- for transition in "${TRANSITIONS[@]}"; do
174
- IFS='|' read -r FROM_PHASE TO_PHASE FROM_AGENT TO_AGENT GATE <<< "$transition"
175
-
176
- # Add phase history row (close out the FROM phase)
177
- # We'll use NOW for ended time since we don't know actual times
178
- PHASE_HISTORY_ADDITIONS+="| $FROM_PHASE | - | $NOW | - |\n"
179
-
180
- # Add handoff history row
181
- HANDOFF_HISTORY_ADDITIONS+="| $FROM_AGENT | $TO_AGENT | $GATE | PASSED | $NOW |\n"
182
- done
183
-
184
- # Update the **Phase:** line
185
- sed -i.bak "s/^\*\*Phase:\*\*.*/\*\*Phase:\*\* $TARGET_PHASE/" "$SESSION_FILE"
186
-
187
- # Update the **Phase Started:** line
188
- sed -i.bak "s/^\*\*Phase Started:\*\*.*/\*\*Phase Started:\*\* $NOW/" "$SESSION_FILE"
189
-
190
- # Close out the current phase in Phase History (update the row that has "| - | - |" at the end)
191
- # This is tricky - we need to find the row for current phase and add end time
192
- # For now, we'll add a note about manual review needed
193
-
194
- # Add handoff history rows before the "## Story Context" section
195
- if [[ -n "$HANDOFF_HISTORY_ADDITIONS" ]]; then
196
- # Find the last handoff history row and add after it
197
- # The handoff history table ends before a blank line or next section
198
-
199
- # Use awk to insert after the last handoff history row
200
- awk -v additions="$HANDOFF_HISTORY_ADDITIONS" '
201
- /^\| .* \| .* \| .* \| .* \| .*\|$/ && /PASSED|FAILED/ {
202
- last_handoff = NR
203
- last_handoff_line = $0
204
- }
205
- {
206
- print
207
- if (NR == last_handoff && additions != "") {
208
- printf "%s", additions
209
- }
210
- }
211
- ' "$SESSION_FILE" > "$SESSION_FILE.tmp" && mv "$SESSION_FILE.tmp" "$SESSION_FILE"
212
- fi
213
-
214
- # Clean up backup
215
- rm -f "$SESSION_FILE.bak"
216
-
217
- echo ""
218
- echo "✓ Session file updated"
219
- echo " Phase: $CURRENT_PHASE → $TARGET_PHASE"
220
- echo " Handoffs added: ${#TRANSITIONS[@]}"
221
- echo ""
222
- echo "Note: Phase History end times set to now. Review and adjust if needed."
2
+ # DEPRECATED: Use `pf workflow fix-phase` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: fix-session-phase.sh is deprecated. Use: pf workflow fix-phase $*" >&2
5
+ exec pf workflow fix-phase "$@"
@@ -1,13 +1,5 @@
1
- #!/usr/bin/env bash
2
- # get-workflow-type.sh - Determine if a workflow is phased or stepped
3
- #
4
- # Usage: .pennyfarthing/scripts/workflow/get-workflow-type.sh <workflow-name>
5
- #
6
- # Returns: "phased" or "stepped"
7
- # Exit 1 if workflow not found
8
-
9
- set -euo pipefail
10
-
11
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
-
13
- exec python3 "$SCRIPT_DIR/get-workflow-type.py" "$@"
1
+ #!/bin/bash
2
+ # DEPRECATED: Use `pf workflow type` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: get-workflow-type.sh is deprecated. Use: pf workflow type $*" >&2
5
+ exec pf workflow type "$@"
@@ -1,124 +1,5 @@
1
1
  #!/bin/bash
2
- # List all available workflows with type indicators
3
- # Usage: .pennyfarthing/scripts/workflow/list-workflows.sh
4
- # or: Invoked with PROJECT_ROOT already set
5
- #
6
- # MSSCI-12083: Added type, steps, and modes columns
7
-
8
- set -euo pipefail
9
-
10
- # Find project root
11
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
12
-
13
- WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
14
-
15
- if [[ ! -d "$WORKFLOWS_DIR" ]]; then
16
- echo "Error: Workflows directory not found at $WORKFLOWS_DIR"
17
- exit 1
18
- fi
19
-
20
- if ! command -v yq &> /dev/null; then
21
- echo "Error: yq is required but not installed"
22
- echo "Install with: brew install yq"
23
- exit 1
24
- fi
25
-
26
- echo "# Available Workflows"
27
- echo ""
28
- echo "| Workflow | Type | Default | Steps/Phases | Modes | Description |"
29
- echo "|----------|------|---------|--------------|-------|-------------|"
30
-
31
- # Find all workflow YAML files: top-level *.yaml and subdirectory workflow.yaml files
32
- workflow_files=()
33
- while IFS= read -r -d '' f; do
34
- workflow_files+=("$f")
35
- done < <(find -L "$WORKFLOWS_DIR" -maxdepth 1 -name "*.yaml" -print0 2>/dev/null)
36
- while IFS= read -r -d '' f; do
37
- workflow_files+=("$f")
38
- done < <(find -L "$WORKFLOWS_DIR" -mindepth 2 -name "workflow.yaml" -print0 2>/dev/null)
39
-
40
- # Exit early if no workflows found
41
- if [[ ${#workflow_files[@]} -eq 0 ]]; then
42
- echo "No workflows found in $WORKFLOWS_DIR"
43
- exit 0
44
- fi
45
-
46
- # Sort by workflow name for consistent output
47
- IFS=$'\n' sorted_files=($(printf '%s\n' "${workflow_files[@]}" | sort))
48
- unset IFS
49
-
50
- for f in "${sorted_files[@]}"; do
51
- [[ -f "$f" ]] || continue
52
-
53
- name=$(yq eval '.workflow.name' "$f")
54
- desc=$(yq eval '.workflow.description' "$f" | head -1)
55
- is_default=$(yq eval '.workflow.triggers.default // false' "$f")
56
-
57
- # Detect workflow type (stepped, phased, or procedural)
58
- # Stepped workflows have .workflow.type == "stepped" or .workflow.steps
59
- # Procedural workflows have .workflow.type == "procedural" (BMAD reference workflows)
60
- workflow_type=$(yq eval '.workflow.type // "phased"' "$f")
61
- has_steps=$(yq eval '.workflow.steps != null' "$f")
62
-
63
- if [[ "$has_steps" == "true" ]] || [[ "$workflow_type" == "stepped" ]]; then
64
- type_col="stepped"
65
- # Count step files if steps.path is defined
66
- steps_path=$(yq eval '.workflow.steps.path // ""' "$f")
67
- steps_pattern=$(yq eval '.workflow.steps.pattern // "step-*.md"' "$f")
68
- # Resolve steps_path relative to the workflow file's directory
69
- workflow_dir=$(dirname "$f")
70
- if [[ -n "$steps_path" ]]; then
71
- # Handle relative paths (./steps/ or steps/)
72
- if [[ "$steps_path" == ./* ]]; then
73
- resolved_path="$workflow_dir/${steps_path#./}"
74
- elif [[ "$steps_path" != /* ]]; then
75
- resolved_path="$workflow_dir/$steps_path"
76
- else
77
- resolved_path="$steps_path"
78
- fi
79
- if [[ -d "$resolved_path" ]]; then
80
- step_count=$(find "$resolved_path" -maxdepth 1 -name "step-*.md" 2>/dev/null | wc -l | tr -d ' ')
81
- steps_col="${step_count} steps"
82
- else
83
- steps_col="-"
84
- fi
85
- else
86
- steps_col="-"
87
- fi
88
- elif [[ "$workflow_type" == "procedural" ]]; then
89
- type_col="procedural"
90
- # Procedural workflows use instructions.md instead of phases/steps
91
- steps_col="instructions"
92
- else
93
- type_col="phased"
94
- # Count phases for phased workflows
95
- phase_count=$(yq eval '.workflow.phases | length' "$f")
96
- steps_col="${phase_count} phases"
97
- fi
98
-
99
- # Default column
100
- if [[ "$is_default" == "true" ]]; then
101
- default_col="yes"
102
- else
103
- default_col="no"
104
- fi
105
-
106
- # Modes column (for tri-modal workflows)
107
- modes=$(yq eval '.workflow.modes.available // []' "$f")
108
- if [[ "$modes" != "[]" ]] && [[ "$modes" != "null" ]]; then
109
- # Format as comma-separated list
110
- modes_col=$(yq eval '.workflow.modes.available | join(",")' "$f")
111
- else
112
- modes_col="-"
113
- fi
114
-
115
- echo "| $name | $type_col | $default_col | $steps_col | $modes_col | $desc |"
116
- done
117
-
118
- echo ""
119
- echo "**Legend:**"
120
- echo "- **phased**: Agent-driven workflow (SM → TEA → Dev → Reviewer)"
121
- echo "- **stepped**: Step-by-step guided workflow with progressive disclosure"
122
- echo "- **procedural**: BMAD reference workflow with instructions file"
123
- echo ""
124
- echo "Use \`/workflow show <name>\` for workflow details."
2
+ # DEPRECATED: Use `pf workflow list` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: list-workflows.sh is deprecated. Use: pf workflow list" >&2
5
+ exec pf workflow list "$@"
@@ -1,34 +1,5 @@
1
1
  #!/bin/bash
2
- # Get the agent that owns a phase in a workflow
3
- # Usage: phase-owner.sh <workflow> <phase>
4
- # Returns: agent name (e.g., "dev", "tea", "reviewer", "sm")
5
-
6
- set -euo pipefail
7
-
8
- WORKFLOW="${1:-}"
9
- PHASE="${2:-}"
10
-
11
- if [[ -z "$WORKFLOW" || -z "$PHASE" ]]; then
12
- echo "Usage: phase-owner.sh <workflow> <phase>" >&2
13
- exit 1
14
- fi
15
-
16
- # Find project root
17
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
18
-
19
- WORKFLOW_FILE="$PROJECT_ROOT/.pennyfarthing/workflows/${WORKFLOW}.yaml"
20
-
21
- if [[ ! -f "$WORKFLOW_FILE" ]]; then
22
- echo "Error: Workflow '$WORKFLOW' not found" >&2
23
- exit 1
24
- fi
25
-
26
- # Query the agent for this phase
27
- AGENT=$(yq eval ".workflow.phases[] | select(.name == \"$PHASE\") | .agent" "$WORKFLOW_FILE" 2>/dev/null)
28
-
29
- if [[ -z "$AGENT" || "$AGENT" == "null" ]]; then
30
- echo "Error: Phase '$PHASE' not found in workflow '$WORKFLOW'" >&2
31
- exit 1
32
- fi
33
-
34
- echo "$AGENT"
2
+ # DEPRECATED: Use `pf workflow phase-check` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: phase-owner.sh is deprecated. Use: pf workflow phase-check $*" >&2
5
+ exec pf workflow phase-check "$@"
@@ -1,157 +1,5 @@
1
1
  #!/bin/bash
2
- # Resume a stepped workflow from last completed step
3
- # Usage: .pennyfarthing/scripts/workflow/resume-workflow.sh [name]
4
- #
5
- # If no name provided, detects from active session
6
-
7
- set -euo pipefail
8
-
9
- # Find project root
10
- source "$(dirname "${BASH_SOURCE[0]}")/../lib/find-root.sh"
11
-
12
- WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
13
- SESSION_DIR="$PROJECT_ROOT/.session"
14
-
15
- if ! command -v yq &> /dev/null; then
16
- echo "Error: yq is required but not installed"
17
- echo "Install with: brew install yq"
18
- exit 1
19
- fi
20
-
21
- WORKFLOW_NAME="${1:-}"
22
-
23
- # If no name, try to detect from session
24
- if [[ -z "$WORKFLOW_NAME" ]]; then
25
- # Look for workflow session files
26
- SESSION_FILE=$(find "$SESSION_DIR" -maxdepth 1 -name "*-workflow-session.md" 2>/dev/null | head -1)
27
-
28
- if [[ -z "$SESSION_FILE" ]]; then
29
- echo "# Resume Stepped Workflow"
30
- echo ""
31
- echo "No active workflow session found."
32
- echo ""
33
- echo "Use \`/workflow start <name>\` to begin a new workflow."
34
- exit 1
35
- fi
36
-
37
- # Extract workflow name from session
38
- WORKFLOW_NAME=$(grep -E "^\*\*Workflow:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/\*\*Workflow:\*\* //' | tr -d ' ')
39
-
40
- if [[ -z "$WORKFLOW_NAME" ]]; then
41
- # Try extracting from filename
42
- WORKFLOW_NAME=$(basename "$SESSION_FILE" | sed 's/-workflow-session.md//')
43
- fi
44
- else
45
- SESSION_FILE="$SESSION_DIR/${WORKFLOW_NAME}-workflow-session.md"
46
- fi
47
-
48
- if [[ ! -f "$SESSION_FILE" ]]; then
49
- echo "Error: No session found for workflow '$WORKFLOW_NAME'"
50
- echo ""
51
- echo "Use \`/workflow start $WORKFLOW_NAME\` to begin."
52
- exit 1
53
- fi
54
-
55
- # Find workflow file
56
- WORKFLOW_FILE=""
57
- if [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml" ]]; then
58
- WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml"
59
- elif [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml" ]]; then
60
- WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml"
61
- else
62
- echo "Error: Workflow definition '$WORKFLOW_NAME' not found"
63
- exit 1
64
- fi
65
-
66
- WORKFLOW_DIR=$(dirname "$WORKFLOW_FILE")
67
-
68
- # Parse session state
69
- CURRENT_STEP=$(grep -E "^\- \*\*Current Step:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "1")
70
- MODE=$(grep -E "^\- \*\*Mode:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "create")
71
- STATUS=$(grep -E "^\- \*\*Status:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "in_progress")
72
- STEPS_COMPLETED=$(grep -E "^\- \*\*Steps Completed:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "[]")
73
-
74
- # Check if workflow is complete
75
- if [[ "$STATUS" == "completed" ]]; then
76
- echo "# Workflow Complete: $WORKFLOW_NAME"
77
- echo ""
78
- echo "This workflow has already been completed."
79
- echo ""
80
- echo "To start a new session, delete the session file:"
81
- echo "\`\`\`bash"
82
- echo "rm \"$SESSION_FILE\""
83
- echo "\`\`\`"
84
- echo ""
85
- echo "Then run \`/workflow start $WORKFLOW_NAME\`"
86
- exit 0
87
- fi
88
-
89
- # Resolve steps path based on mode
90
- MODE_PATH=$(yq eval ".workflow.modes.$MODE // \"\"" "$WORKFLOW_FILE")
91
- if [[ -n "$MODE_PATH" && "$MODE_PATH" != "null" ]]; then
92
- STEPS_PATH="$MODE_PATH"
93
- else
94
- STEPS_PATH=$(yq eval '.workflow.steps.path' "$WORKFLOW_FILE")
95
- fi
96
-
97
- # Resolve relative path
98
- if [[ "$STEPS_PATH" == ./* ]]; then
99
- STEPS_PATH="$WORKFLOW_DIR/${STEPS_PATH#./}"
100
- elif [[ "$STEPS_PATH" != /* ]]; then
101
- STEPS_PATH="$PROJECT_ROOT/$STEPS_PATH"
102
- fi
103
-
104
- # Count steps
105
- STEP_COUNT=$(find "$STEPS_PATH" -maxdepth 1 -name "step-0*.md" -o -name "step-1*.md" 2>/dev/null | wc -l | tr -d ' ')
106
-
107
- # Find the current step file
108
- # Handle various naming: step-01.md, step-01-name.md, step-1-name.md
109
- PADDED_STEP=$(printf "%02d" "$CURRENT_STEP")
110
- STEP_FILE=$(find "$STEPS_PATH" -maxdepth 1 \( -name "step-${PADDED_STEP}*.md" -o -name "step-${CURRENT_STEP}-*.md" \) 2>/dev/null | sort | head -1)
111
-
112
- if [[ -z "$STEP_FILE" ]]; then
113
- echo "Error: Could not find step $CURRENT_STEP file in $STEPS_PATH"
114
- exit 1
115
- fi
116
-
117
- # Update last updated timestamp
118
- NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
119
- sed -i '' "s/^\- \*\*Last Updated:\*\*.*/- **Last Updated:** $NOW/" "$SESSION_FILE" 2>/dev/null || true
120
-
121
- # Calculate completion percentage
122
- COMPLETED_COUNT=$(echo "$STEPS_COMPLETED" | tr -cd ',' | wc -c | tr -d ' ')
123
- if [[ "$STEPS_COMPLETED" != "[]" ]]; then
124
- COMPLETED_COUNT=$((COMPLETED_COUNT + 1))
125
- fi
126
- if [[ "$STEP_COUNT" -gt 0 ]]; then
127
- COMPLETION_PCT=$((COMPLETED_COUNT * 100 / STEP_COUNT))
128
- else
129
- COMPLETION_PCT=0
130
- fi
131
-
132
- # Output resume info
133
- echo "# Resuming Workflow: $WORKFLOW_NAME"
134
- echo ""
135
- echo "**Mode:** $MODE"
136
- echo "**Progress:** Step $CURRENT_STEP of $STEP_COUNT ($COMPLETION_PCT% complete)"
137
- echo "**Steps Completed:** $STEPS_COMPLETED"
138
- echo "**Session:** $SESSION_FILE"
139
- echo ""
140
- echo "---"
141
- echo ""
142
- echo "## Step $CURRENT_STEP of $STEP_COUNT"
143
- echo ""
144
-
145
- # Output step content (strip frontmatter if present)
146
- if head -1 "$STEP_FILE" | grep -q "^---$"; then
147
- awk '/^---$/{if(++c==2){p=1;next}}p' "$STEP_FILE"
148
- else
149
- cat "$STEP_FILE"
150
- fi
151
-
152
- echo ""
153
- echo "---"
154
- echo ""
155
- echo "**Controls:**"
156
- echo "- \`C\` - Continue to next step"
157
- echo "- \`/workflow status\` - Check progress"
2
+ # DEPRECATED: Use `pf workflow resume` instead.
3
+ # This shim forwards to the Python CLI for backward compatibility.
4
+ echo "Warning: resume-workflow.sh is deprecated. Use: pf workflow resume $*" >&2
5
+ exec pf workflow resume "$@"