@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.
- package/README.md +8 -8
- package/package.json +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/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/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/pennyfarthing-dist/agents/dev.md +1 -1
- package/pennyfarthing-dist/agents/reviewer.md +1 -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-standalone.md +7 -2
- package/pennyfarthing-dist/guides/agent-behavior.md +1 -1
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +1 -1
- package/pennyfarthing-dist/guides/bikerack.md +3 -3
- package/pennyfarthing-dist/guides/hooks.md +1 -1
- 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 +1 -1
- 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 +1 -1
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +1 -1
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +9 -11
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +1 -1
- 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/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_scripts/CLAUDE.md +26 -4
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/cli.py +3 -5
- 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__/debug_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.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.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__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/background_panel.py +86 -5
- package/pennyfarthing_scripts/bikerack/base_panel.py +62 -0
- package/pennyfarthing_scripts/bikerack/changed_panel.py +32 -28
- package/pennyfarthing_scripts/bikerack/debug_panel.py +31 -1
- package/pennyfarthing_scripts/bikerack/diffs_panel.py +74 -17
- package/pennyfarthing_scripts/bikerack/git_panel.py +103 -33
- package/pennyfarthing_scripts/bikerack/launcher.py +15 -15
- package/pennyfarthing_scripts/bikerack/progress_panel.py +315 -0
- package/pennyfarthing_scripts/bikerack/sprint_panel.py +158 -26
- package/pennyfarthing_scripts/bikerack/tui.py +336 -30
- package/pennyfarthing_scripts/bikerack/ws_client.py +2 -2
- package/pennyfarthing_scripts/cli.py +37 -65
- 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/cli.py +149 -0
- package/pennyfarthing_scripts/consultation/dialogue_manager.py +417 -0
- package/pennyfarthing_scripts/context.py +3 -3
- 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__/hooks_installer.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/repos.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/worktree.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__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/complete_phase.py +12 -0
- package/pennyfarthing_scripts/handoff/resolve_gate.py +5 -14
- package/pennyfarthing_scripts/hooks.py +3 -17
- package/pennyfarthing_scripts/pretooluse_hook.py +1 -1
- package/pennyfarthing_scripts/prime/__pycache__/heatmap.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/heatmap.py +655 -0
- 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 +1 -1
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/loader.py +15 -1
- 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_workflow_check.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_workflow_check.py +2 -3
- package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/tandem_awareness.py +254 -0
- package/pennyfarthing_scripts/validate/cli.py +17 -5
- 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 +1099 -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-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
|
@@ -1,163 +0,0 @@
|
|
|
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
|
-
# PROJECT_ROOT should be set by find-root.sh, but find it if not
|
|
10
|
-
if [[ -z "${PROJECT_ROOT:-}" ]]; then
|
|
11
|
-
d="$PWD"
|
|
12
|
-
while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do
|
|
13
|
-
d="$(dirname "$d")"
|
|
14
|
-
done
|
|
15
|
-
PROJECT_ROOT="$d"
|
|
16
|
-
fi
|
|
17
|
-
|
|
18
|
-
WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
|
|
19
|
-
SESSION_DIR="$PROJECT_ROOT/.session"
|
|
20
|
-
|
|
21
|
-
if ! command -v yq &> /dev/null; then
|
|
22
|
-
echo "Error: yq is required but not installed"
|
|
23
|
-
echo "Install with: brew install yq"
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
WORKFLOW_NAME="${1:-}"
|
|
28
|
-
|
|
29
|
-
# If no name, try to detect from session
|
|
30
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
31
|
-
# Look for workflow session files
|
|
32
|
-
SESSION_FILE=$(find "$SESSION_DIR" -maxdepth 1 -name "*-workflow-session.md" 2>/dev/null | head -1)
|
|
33
|
-
|
|
34
|
-
if [[ -z "$SESSION_FILE" ]]; then
|
|
35
|
-
echo "# Resume Stepped Workflow"
|
|
36
|
-
echo ""
|
|
37
|
-
echo "No active workflow session found."
|
|
38
|
-
echo ""
|
|
39
|
-
echo "Use \`/workflow start <name>\` to begin a new workflow."
|
|
40
|
-
exit 1
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
# Extract workflow name from session
|
|
44
|
-
WORKFLOW_NAME=$(grep -E "^\*\*Workflow:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/\*\*Workflow:\*\* //' | tr -d ' ')
|
|
45
|
-
|
|
46
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
47
|
-
# Try extracting from filename
|
|
48
|
-
WORKFLOW_NAME=$(basename "$SESSION_FILE" | sed 's/-workflow-session.md//')
|
|
49
|
-
fi
|
|
50
|
-
else
|
|
51
|
-
SESSION_FILE="$SESSION_DIR/${WORKFLOW_NAME}-workflow-session.md"
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
if [[ ! -f "$SESSION_FILE" ]]; then
|
|
55
|
-
echo "Error: No session found for workflow '$WORKFLOW_NAME'"
|
|
56
|
-
echo ""
|
|
57
|
-
echo "Use \`/workflow start $WORKFLOW_NAME\` to begin."
|
|
58
|
-
exit 1
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
# Find workflow file
|
|
62
|
-
WORKFLOW_FILE=""
|
|
63
|
-
if [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml" ]]; then
|
|
64
|
-
WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml"
|
|
65
|
-
elif [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml" ]]; then
|
|
66
|
-
WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml"
|
|
67
|
-
else
|
|
68
|
-
echo "Error: Workflow definition '$WORKFLOW_NAME' not found"
|
|
69
|
-
exit 1
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
WORKFLOW_DIR=$(dirname "$WORKFLOW_FILE")
|
|
73
|
-
|
|
74
|
-
# Parse session state
|
|
75
|
-
CURRENT_STEP=$(grep -E "^\- \*\*Current Step:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "1")
|
|
76
|
-
MODE=$(grep -E "^\- \*\*Mode:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "create")
|
|
77
|
-
STATUS=$(grep -E "^\- \*\*Status:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "in_progress")
|
|
78
|
-
STEPS_COMPLETED=$(grep -E "^\- \*\*Steps Completed:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' || echo "[]")
|
|
79
|
-
|
|
80
|
-
# Check if workflow is complete
|
|
81
|
-
if [[ "$STATUS" == "completed" ]]; then
|
|
82
|
-
echo "# Workflow Complete: $WORKFLOW_NAME"
|
|
83
|
-
echo ""
|
|
84
|
-
echo "This workflow has already been completed."
|
|
85
|
-
echo ""
|
|
86
|
-
echo "To start a new session, delete the session file:"
|
|
87
|
-
echo "\`\`\`bash"
|
|
88
|
-
echo "rm \"$SESSION_FILE\""
|
|
89
|
-
echo "\`\`\`"
|
|
90
|
-
echo ""
|
|
91
|
-
echo "Then run \`/workflow start $WORKFLOW_NAME\`"
|
|
92
|
-
exit 0
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# Resolve steps path based on mode
|
|
96
|
-
MODE_PATH=$(yq eval ".workflow.modes.$MODE // \"\"" "$WORKFLOW_FILE")
|
|
97
|
-
if [[ -n "$MODE_PATH" && "$MODE_PATH" != "null" ]]; then
|
|
98
|
-
STEPS_PATH="$MODE_PATH"
|
|
99
|
-
else
|
|
100
|
-
STEPS_PATH=$(yq eval '.workflow.steps.path' "$WORKFLOW_FILE")
|
|
101
|
-
fi
|
|
102
|
-
|
|
103
|
-
# Resolve relative path
|
|
104
|
-
if [[ "$STEPS_PATH" == ./* ]]; then
|
|
105
|
-
STEPS_PATH="$WORKFLOW_DIR/${STEPS_PATH#./}"
|
|
106
|
-
elif [[ "$STEPS_PATH" != /* ]]; then
|
|
107
|
-
STEPS_PATH="$PROJECT_ROOT/$STEPS_PATH"
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# Count steps
|
|
111
|
-
STEP_COUNT=$(find "$STEPS_PATH" -maxdepth 1 -name "step-0*.md" -o -name "step-1*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
112
|
-
|
|
113
|
-
# Find the current step file
|
|
114
|
-
# Handle various naming: step-01.md, step-01-name.md, step-1-name.md
|
|
115
|
-
PADDED_STEP=$(printf "%02d" "$CURRENT_STEP")
|
|
116
|
-
STEP_FILE=$(find "$STEPS_PATH" -maxdepth 1 \( -name "step-${PADDED_STEP}*.md" -o -name "step-${CURRENT_STEP}-*.md" \) 2>/dev/null | sort | head -1)
|
|
117
|
-
|
|
118
|
-
if [[ -z "$STEP_FILE" ]]; then
|
|
119
|
-
echo "Error: Could not find step $CURRENT_STEP file in $STEPS_PATH"
|
|
120
|
-
exit 1
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
# Update last updated timestamp
|
|
124
|
-
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
125
|
-
sed -i '' "s/^\- \*\*Last Updated:\*\*.*/- **Last Updated:** $NOW/" "$SESSION_FILE" 2>/dev/null || true
|
|
126
|
-
|
|
127
|
-
# Calculate completion percentage
|
|
128
|
-
COMPLETED_COUNT=$(echo "$STEPS_COMPLETED" | tr -cd ',' | wc -c | tr -d ' ')
|
|
129
|
-
if [[ "$STEPS_COMPLETED" != "[]" ]]; then
|
|
130
|
-
COMPLETED_COUNT=$((COMPLETED_COUNT + 1))
|
|
131
|
-
fi
|
|
132
|
-
if [[ "$STEP_COUNT" -gt 0 ]]; then
|
|
133
|
-
COMPLETION_PCT=$((COMPLETED_COUNT * 100 / STEP_COUNT))
|
|
134
|
-
else
|
|
135
|
-
COMPLETION_PCT=0
|
|
136
|
-
fi
|
|
137
|
-
|
|
138
|
-
# Output resume info
|
|
139
|
-
echo "# Resuming Workflow: $WORKFLOW_NAME"
|
|
140
|
-
echo ""
|
|
141
|
-
echo "**Mode:** $MODE"
|
|
142
|
-
echo "**Progress:** Step $CURRENT_STEP of $STEP_COUNT ($COMPLETION_PCT% complete)"
|
|
143
|
-
echo "**Steps Completed:** $STEPS_COMPLETED"
|
|
144
|
-
echo "**Session:** $SESSION_FILE"
|
|
145
|
-
echo ""
|
|
146
|
-
echo "---"
|
|
147
|
-
echo ""
|
|
148
|
-
echo "## Step $CURRENT_STEP of $STEP_COUNT"
|
|
149
|
-
echo ""
|
|
150
|
-
|
|
151
|
-
# Output step content (strip frontmatter if present)
|
|
152
|
-
if head -1 "$STEP_FILE" | grep -q "^---$"; then
|
|
153
|
-
awk '/^---$/{if(++c==2){p=1;next}}p' "$STEP_FILE"
|
|
154
|
-
else
|
|
155
|
-
cat "$STEP_FILE"
|
|
156
|
-
fi
|
|
157
|
-
|
|
158
|
-
echo ""
|
|
159
|
-
echo "---"
|
|
160
|
-
echo ""
|
|
161
|
-
echo "**Controls:**"
|
|
162
|
-
echo "- \`C\` - Continue to next step"
|
|
163
|
-
echo "- \`/workflow status\` - Check progress"
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Show workflow details
|
|
3
|
-
# Usage: .pennyfarthing/scripts/workflow/show-workflow.sh [name]
|
|
4
|
-
# or: Invoked with PROJECT_ROOT already set
|
|
5
|
-
#
|
|
6
|
-
# If no name provided, shows current session's workflow
|
|
7
|
-
# If name provided, shows that workflow's details
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
# PROJECT_ROOT should be set by find-root.sh, but find it if not
|
|
12
|
-
if [[ -z "${PROJECT_ROOT:-}" ]]; then
|
|
13
|
-
d="$PWD"
|
|
14
|
-
while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do
|
|
15
|
-
d="$(dirname "$d")"
|
|
16
|
-
done
|
|
17
|
-
PROJECT_ROOT="$d"
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
|
|
21
|
-
SESSION_DIR="$PROJECT_ROOT/.session"
|
|
22
|
-
|
|
23
|
-
if ! command -v yq &> /dev/null; then
|
|
24
|
-
echo "Error: yq is required but not installed"
|
|
25
|
-
echo "Install with: brew install yq"
|
|
26
|
-
exit 1
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Get workflow name from argument or session
|
|
30
|
-
WORKFLOW_NAME="${1:-}"
|
|
31
|
-
|
|
32
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
33
|
-
# Try to get from current session (exclude archive directory)
|
|
34
|
-
SESSION_FILE=$(find "$SESSION_DIR" -maxdepth 1 -name "*-session.md" 2>/dev/null | head -1)
|
|
35
|
-
if [[ -n "$SESSION_FILE" ]]; then
|
|
36
|
-
# Extract workflow from session file (look for **Workflow:** line)
|
|
37
|
-
WORKFLOW_NAME=$(grep -E "^\*\*Workflow:\*\*" "$SESSION_FILE" 2>/dev/null | sed 's/.*\*\* //' | tr -d ' ' || echo "")
|
|
38
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
39
|
-
# Try alternate format (Workflow: value in tracking section)
|
|
40
|
-
WORKFLOW_NAME=$(grep -E "^Workflow:" "$SESSION_FILE" 2>/dev/null | head -1 | cut -d: -f2 | tr -d ' ' || echo "")
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
45
|
-
echo "# Current Workflow"
|
|
46
|
-
echo ""
|
|
47
|
-
echo "No active session found. Showing default workflow (tdd)."
|
|
48
|
-
echo ""
|
|
49
|
-
WORKFLOW_NAME="tdd"
|
|
50
|
-
else
|
|
51
|
-
echo "# Current Session Workflow: $WORKFLOW_NAME"
|
|
52
|
-
echo ""
|
|
53
|
-
fi
|
|
54
|
-
else
|
|
55
|
-
echo "# Workflow: $WORKFLOW_NAME"
|
|
56
|
-
echo ""
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml"
|
|
60
|
-
|
|
61
|
-
if [[ ! -f "$WORKFLOW_FILE" ]]; then
|
|
62
|
-
echo "Error: Workflow '$WORKFLOW_NAME' not found"
|
|
63
|
-
echo ""
|
|
64
|
-
echo "Available workflows:"
|
|
65
|
-
for f in "$WORKFLOWS_DIR"/*.yaml; do
|
|
66
|
-
[[ -f "$f" ]] || continue
|
|
67
|
-
basename "$f" .yaml
|
|
68
|
-
done
|
|
69
|
-
exit 1
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# Extract workflow details
|
|
73
|
-
DESC=$(yq eval '.workflow.description' "$WORKFLOW_FILE")
|
|
74
|
-
VERSION=$(yq eval '.workflow.version' "$WORKFLOW_FILE")
|
|
75
|
-
|
|
76
|
-
echo "**Description:** $DESC"
|
|
77
|
-
echo "**Version:** $VERSION"
|
|
78
|
-
echo ""
|
|
79
|
-
|
|
80
|
-
# Show phases as a flow diagram
|
|
81
|
-
echo "## Phase Flow"
|
|
82
|
-
echo ""
|
|
83
|
-
echo -n "\`\`\`"
|
|
84
|
-
echo ""
|
|
85
|
-
|
|
86
|
-
# Build phase flow string
|
|
87
|
-
PHASES=""
|
|
88
|
-
yq eval '.workflow.phases[].name' "$WORKFLOW_FILE" | while read -r phase; do
|
|
89
|
-
if [[ -n "$PHASES" ]]; then
|
|
90
|
-
echo -n " -> "
|
|
91
|
-
fi
|
|
92
|
-
echo -n "$phase"
|
|
93
|
-
PHASES="$phase"
|
|
94
|
-
done
|
|
95
|
-
echo ""
|
|
96
|
-
echo "\`\`\`"
|
|
97
|
-
echo ""
|
|
98
|
-
|
|
99
|
-
# Show phases table
|
|
100
|
-
echo "## Phases"
|
|
101
|
-
echo ""
|
|
102
|
-
echo "| Phase | Agent | Gate |"
|
|
103
|
-
echo "|-------|-------|------|"
|
|
104
|
-
|
|
105
|
-
yq eval '.workflow.phases[] | .name + "|" + .agent + "|" + (.gate.type // "none")' "$WORKFLOW_FILE" | while IFS='|' read -r phase agent gate; do
|
|
106
|
-
echo "| $phase | $agent | $gate |"
|
|
107
|
-
done
|
|
108
|
-
|
|
109
|
-
echo ""
|
|
110
|
-
|
|
111
|
-
# Show triggers
|
|
112
|
-
echo "## Triggers"
|
|
113
|
-
echo ""
|
|
114
|
-
|
|
115
|
-
TYPES=$(yq eval '.workflow.triggers.types // []' "$WORKFLOW_FILE")
|
|
116
|
-
if [[ "$TYPES" != "[]" && "$TYPES" != "null" ]]; then
|
|
117
|
-
echo "**Types:** $(yq eval '.workflow.triggers.types | join(", ")' "$WORKFLOW_FILE")"
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
POINTS_MIN=$(yq eval '.workflow.triggers.points.min // ""' "$WORKFLOW_FILE")
|
|
121
|
-
POINTS_MAX=$(yq eval '.workflow.triggers.points.max // ""' "$WORKFLOW_FILE")
|
|
122
|
-
|
|
123
|
-
if [[ -n "$POINTS_MIN" && "$POINTS_MIN" != "null" ]]; then
|
|
124
|
-
echo "**Points Min:** $POINTS_MIN"
|
|
125
|
-
fi
|
|
126
|
-
if [[ -n "$POINTS_MAX" && "$POINTS_MAX" != "null" ]]; then
|
|
127
|
-
echo "**Points Max:** $POINTS_MAX"
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
IS_DEFAULT=$(yq eval '.workflow.triggers.default // false' "$WORKFLOW_FILE")
|
|
131
|
-
if [[ "$IS_DEFAULT" == "true" ]]; then
|
|
132
|
-
echo "**Default:** yes (used when no other workflow matches)"
|
|
133
|
-
fi
|
|
134
|
-
|
|
135
|
-
TAGS=$(yq eval '.workflow.triggers.tags // []' "$WORKFLOW_FILE")
|
|
136
|
-
if [[ "$TAGS" != "[]" && "$TAGS" != "null" ]]; then
|
|
137
|
-
echo "**Tags:** $(yq eval '.workflow.triggers.tags | join(", ")' "$WORKFLOW_FILE")"
|
|
138
|
-
fi
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Start a stepped workflow
|
|
3
|
-
# Usage: .pennyfarthing/scripts/workflow/start-workflow.sh <name> [--mode create|validate|edit]
|
|
4
|
-
#
|
|
5
|
-
# Creates a new workflow session and loads step 1.
|
|
6
|
-
# For tri-modal workflows, --mode selects the step path (default: create)
|
|
7
|
-
|
|
8
|
-
set -euo pipefail
|
|
9
|
-
|
|
10
|
-
# PROJECT_ROOT should be set by find-root.sh, but find it if not
|
|
11
|
-
if [[ -z "${PROJECT_ROOT:-}" ]]; then
|
|
12
|
-
d="$PWD"
|
|
13
|
-
while [[ ! -d "$d/.claude" ]] && [[ "$d" != "/" ]]; do
|
|
14
|
-
d="$(dirname "$d")"
|
|
15
|
-
done
|
|
16
|
-
PROJECT_ROOT="$d"
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
WORKFLOWS_DIR="$PROJECT_ROOT/.pennyfarthing/workflows"
|
|
20
|
-
SESSION_DIR="$PROJECT_ROOT/.session"
|
|
21
|
-
|
|
22
|
-
if ! command -v yq &> /dev/null; then
|
|
23
|
-
echo "Error: yq is required but not installed"
|
|
24
|
-
echo "Install with: brew install yq"
|
|
25
|
-
exit 1
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
# Parse arguments
|
|
29
|
-
WORKFLOW_NAME=""
|
|
30
|
-
MODE=""
|
|
31
|
-
ARGS=("$@")
|
|
32
|
-
|
|
33
|
-
i=0
|
|
34
|
-
while [[ $i -lt ${#ARGS[@]} ]]; do
|
|
35
|
-
arg="${ARGS[$i]}"
|
|
36
|
-
case "$arg" in
|
|
37
|
-
--mode=*)
|
|
38
|
-
MODE="${arg#--mode=}"
|
|
39
|
-
;;
|
|
40
|
-
--mode|-m)
|
|
41
|
-
if [[ $((i+1)) -lt ${#ARGS[@]} ]]; then
|
|
42
|
-
((i++))
|
|
43
|
-
MODE="${ARGS[$i]}"
|
|
44
|
-
else
|
|
45
|
-
echo "Error: --mode requires a value (create, validate, or edit)"
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
;;
|
|
49
|
-
-*)
|
|
50
|
-
echo "Error: Unknown option: $arg"
|
|
51
|
-
echo "Usage: start-workflow.sh <name> [--mode create|validate|edit]"
|
|
52
|
-
exit 1
|
|
53
|
-
;;
|
|
54
|
-
*)
|
|
55
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
56
|
-
WORKFLOW_NAME="$arg"
|
|
57
|
-
else
|
|
58
|
-
echo "Error: Unexpected argument: $arg"
|
|
59
|
-
exit 1
|
|
60
|
-
fi
|
|
61
|
-
;;
|
|
62
|
-
esac
|
|
63
|
-
((i++))
|
|
64
|
-
done
|
|
65
|
-
|
|
66
|
-
if [[ -z "$WORKFLOW_NAME" ]]; then
|
|
67
|
-
echo "# Start Stepped Workflow"
|
|
68
|
-
echo ""
|
|
69
|
-
echo "Usage: /workflow start <name> [--mode create|validate|edit]"
|
|
70
|
-
echo ""
|
|
71
|
-
echo "**Available stepped workflows:**"
|
|
72
|
-
echo ""
|
|
73
|
-
for f in "$WORKFLOWS_DIR"/*.yaml "$WORKFLOWS_DIR"/*/workflow.yaml; do
|
|
74
|
-
[[ -f "$f" ]] || continue
|
|
75
|
-
workflow_type=$(yq eval '.workflow.type // "phased"' "$f")
|
|
76
|
-
if [[ "$workflow_type" == "stepped" ]]; then
|
|
77
|
-
name=$(yq eval '.workflow.name' "$f")
|
|
78
|
-
desc=$(yq eval '.workflow.description' "$f" | head -1 | cut -c1-60)
|
|
79
|
-
echo "- **$name** - $desc"
|
|
80
|
-
fi
|
|
81
|
-
done
|
|
82
|
-
exit 1
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
# Find workflow file (support both flat and directory structure)
|
|
86
|
-
WORKFLOW_FILE=""
|
|
87
|
-
if [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml" ]]; then
|
|
88
|
-
WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml"
|
|
89
|
-
elif [[ -f "$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml" ]]; then
|
|
90
|
-
WORKFLOW_FILE="$WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml"
|
|
91
|
-
else
|
|
92
|
-
echo "Error: Workflow '$WORKFLOW_NAME' not found"
|
|
93
|
-
echo ""
|
|
94
|
-
echo "Looked in:"
|
|
95
|
-
echo " $WORKFLOWS_DIR/${WORKFLOW_NAME}.yaml"
|
|
96
|
-
echo " $WORKFLOWS_DIR/${WORKFLOW_NAME}/workflow.yaml"
|
|
97
|
-
exit 1
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
WORKFLOW_DIR=$(dirname "$WORKFLOW_FILE")
|
|
101
|
-
|
|
102
|
-
# Validate it's a stepped workflow
|
|
103
|
-
WORKFLOW_TYPE=$(yq eval '.workflow.type // "phased"' "$WORKFLOW_FILE")
|
|
104
|
-
if [[ "$WORKFLOW_TYPE" != "stepped" ]]; then
|
|
105
|
-
echo "Error: '$WORKFLOW_NAME' is a phased workflow, not stepped"
|
|
106
|
-
echo "Use TDD workflow commands (/sm, /tea, /dev, /reviewer) for phased workflows"
|
|
107
|
-
exit 1
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# Validate mode if provided
|
|
111
|
-
if [[ -n "$MODE" ]]; then
|
|
112
|
-
case "$MODE" in
|
|
113
|
-
create|validate|edit)
|
|
114
|
-
;;
|
|
115
|
-
*)
|
|
116
|
-
echo "Error: Invalid mode '$MODE'. Must be one of: create, validate, edit"
|
|
117
|
-
exit 1
|
|
118
|
-
;;
|
|
119
|
-
esac
|
|
120
|
-
fi
|
|
121
|
-
|
|
122
|
-
# Get workflow info
|
|
123
|
-
WORKFLOW_DESC=$(yq eval '.workflow.description' "$WORKFLOW_FILE")
|
|
124
|
-
WORKFLOW_AGENT=$(yq eval '.workflow.agent // "pm"' "$WORKFLOW_FILE")
|
|
125
|
-
|
|
126
|
-
# Resolve steps path based on mode
|
|
127
|
-
if [[ -n "$MODE" ]]; then
|
|
128
|
-
MODE_PATH=$(yq eval ".workflow.modes.$MODE // \"\"" "$WORKFLOW_FILE")
|
|
129
|
-
if [[ -z "$MODE_PATH" || "$MODE_PATH" == "null" ]]; then
|
|
130
|
-
AVAILABLE_MODES=$(yq eval '.workflow.modes | keys | .[]' "$WORKFLOW_FILE" 2>/dev/null | grep -v default | tr '\n' ', ' | sed 's/,$//')
|
|
131
|
-
echo "Error: Mode '$MODE' not available for workflow '$WORKFLOW_NAME'"
|
|
132
|
-
echo "Available modes: $AVAILABLE_MODES"
|
|
133
|
-
exit 1
|
|
134
|
-
fi
|
|
135
|
-
STEPS_PATH="$MODE_PATH"
|
|
136
|
-
else
|
|
137
|
-
# Use default mode or steps.path
|
|
138
|
-
DEFAULT_MODE=$(yq eval '.workflow.modes.default // ""' "$WORKFLOW_FILE")
|
|
139
|
-
if [[ -n "$DEFAULT_MODE" && "$DEFAULT_MODE" != "null" ]]; then
|
|
140
|
-
MODE_PATH=$(yq eval ".workflow.modes.$DEFAULT_MODE // \"\"" "$WORKFLOW_FILE")
|
|
141
|
-
if [[ -n "$MODE_PATH" && "$MODE_PATH" != "null" ]]; then
|
|
142
|
-
STEPS_PATH="$MODE_PATH"
|
|
143
|
-
MODE="$DEFAULT_MODE"
|
|
144
|
-
fi
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
if [[ -z "${STEPS_PATH:-}" ]]; then
|
|
148
|
-
STEPS_PATH=$(yq eval '.workflow.steps.path' "$WORKFLOW_FILE")
|
|
149
|
-
MODE="${MODE:-create}"
|
|
150
|
-
fi
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
# Resolve relative path
|
|
154
|
-
if [[ "$STEPS_PATH" == ./* ]]; then
|
|
155
|
-
STEPS_PATH="$WORKFLOW_DIR/${STEPS_PATH#./}"
|
|
156
|
-
elif [[ "$STEPS_PATH" != /* ]]; then
|
|
157
|
-
STEPS_PATH="$PROJECT_ROOT/$STEPS_PATH"
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
# Count steps
|
|
161
|
-
STEPS_PATTERN=$(yq eval '.workflow.steps.pattern // "step-*.md"' "$WORKFLOW_FILE")
|
|
162
|
-
STEP_COUNT=$(find "$STEPS_PATH" -maxdepth 1 -name "step-0*.md" -o -name "step-1*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
163
|
-
|
|
164
|
-
if [[ "$STEP_COUNT" -eq 0 ]]; then
|
|
165
|
-
echo "Error: No step files found in $STEPS_PATH"
|
|
166
|
-
exit 1
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
# Create session directory
|
|
170
|
-
mkdir -p "$SESSION_DIR"
|
|
171
|
-
|
|
172
|
-
# Generate session filename
|
|
173
|
-
SESSION_FILE="$SESSION_DIR/${WORKFLOW_NAME}-workflow-session.md"
|
|
174
|
-
|
|
175
|
-
# Check for existing session
|
|
176
|
-
if [[ -f "$SESSION_FILE" ]]; then
|
|
177
|
-
echo "**Warning:** Existing session found"
|
|
178
|
-
echo ""
|
|
179
|
-
echo "Session: $SESSION_FILE"
|
|
180
|
-
echo ""
|
|
181
|
-
echo "Options:"
|
|
182
|
-
echo "1. Use \`/workflow resume $WORKFLOW_NAME\` to continue"
|
|
183
|
-
echo "2. Delete the session file to start fresh"
|
|
184
|
-
echo ""
|
|
185
|
-
echo "To start fresh, run:"
|
|
186
|
-
echo "\`\`\`bash"
|
|
187
|
-
echo "rm \"$SESSION_FILE\""
|
|
188
|
-
echo "\`\`\`"
|
|
189
|
-
exit 0
|
|
190
|
-
fi
|
|
191
|
-
|
|
192
|
-
# Create initial session file
|
|
193
|
-
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
194
|
-
cat > "$SESSION_FILE" << EOF
|
|
195
|
-
# Workflow Session: $WORKFLOW_NAME
|
|
196
|
-
|
|
197
|
-
**Workflow:** $WORKFLOW_NAME
|
|
198
|
-
**Type:** stepped
|
|
199
|
-
**Agent:** $WORKFLOW_AGENT
|
|
200
|
-
**Started:** $NOW
|
|
201
|
-
|
|
202
|
-
## Workflow State
|
|
203
|
-
- **Workflow Name:** $WORKFLOW_NAME
|
|
204
|
-
- **Type:** stepped
|
|
205
|
-
- **Mode:** $MODE
|
|
206
|
-
- **Started:** $NOW
|
|
207
|
-
- **Last Updated:** $NOW
|
|
208
|
-
- **Current Step:** 1
|
|
209
|
-
- **Steps Completed:** []
|
|
210
|
-
- **Status:** in_progress
|
|
211
|
-
- **Notes:** Session created via /workflow start
|
|
212
|
-
|
|
213
|
-
## Progress
|
|
214
|
-
- Total Steps: $STEP_COUNT
|
|
215
|
-
- Completion: 0%
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
EOF
|
|
220
|
-
|
|
221
|
-
# Find step 1 file (handle various naming patterns)
|
|
222
|
-
STEP_FILE=$(find "$STEPS_PATH" -maxdepth 1 \( -name "step-01*.md" -o -name "step-1-*.md" \) 2>/dev/null | sort | head -1)
|
|
223
|
-
|
|
224
|
-
if [[ -z "$STEP_FILE" ]]; then
|
|
225
|
-
echo "Error: Could not find step 1 file in $STEPS_PATH"
|
|
226
|
-
exit 1
|
|
227
|
-
fi
|
|
228
|
-
|
|
229
|
-
# Output workflow start info
|
|
230
|
-
echo "# Starting Workflow: $WORKFLOW_NAME"
|
|
231
|
-
echo ""
|
|
232
|
-
echo "**Description:** $WORKFLOW_DESC"
|
|
233
|
-
echo "**Mode:** $MODE"
|
|
234
|
-
echo "**Steps:** $STEP_COUNT"
|
|
235
|
-
echo "**Agent:** $WORKFLOW_AGENT"
|
|
236
|
-
echo "**Session:** $SESSION_FILE"
|
|
237
|
-
echo ""
|
|
238
|
-
|
|
239
|
-
# Check if auto-handoff is enabled (turbo mode)
|
|
240
|
-
CONFIG_FILE="$PROJECT_ROOT/.pennyfarthing/config.local.yaml"
|
|
241
|
-
HANDOFF_MODE="manual"
|
|
242
|
-
if [[ -f "$CONFIG_FILE" ]]; then
|
|
243
|
-
HANDOFF_MODE=$(yq eval '.workflow.handoff_mode // "manual"' "$CONFIG_FILE")
|
|
244
|
-
fi
|
|
245
|
-
|
|
246
|
-
# Emit Reflector directive - auto-invoke if in turbo mode, else show button
|
|
247
|
-
if [[ "$HANDOFF_MODE" == "auto" ]]; then
|
|
248
|
-
echo "**Auto-handoff enabled.** Invoking /$WORKFLOW_AGENT agent..."
|
|
249
|
-
echo ""
|
|
250
|
-
echo "<!-- CYCLIST:INVOKE:/$WORKFLOW_AGENT -->"
|
|
251
|
-
else
|
|
252
|
-
echo "<!-- CYCLIST:HANDOFF:/$WORKFLOW_AGENT -->"
|
|
253
|
-
fi
|
|
254
|
-
echo ""
|
|
255
|
-
echo "---"
|
|
256
|
-
echo ""
|
|
257
|
-
echo "## Step 1 of $STEP_COUNT"
|
|
258
|
-
echo ""
|
|
259
|
-
|
|
260
|
-
# Output step content (strip frontmatter if present)
|
|
261
|
-
if head -1 "$STEP_FILE" | grep -q "^---$"; then
|
|
262
|
-
awk '/^---$/{if(++c==2){p=1;next}}p' "$STEP_FILE"
|
|
263
|
-
else
|
|
264
|
-
cat "$STEP_FILE"
|
|
265
|
-
fi
|
|
266
|
-
|
|
267
|
-
echo ""
|
|
268
|
-
echo "---"
|
|
269
|
-
echo ""
|
|
270
|
-
echo "**Controls:**"
|
|
271
|
-
echo "- \`C\` - Continue to next step"
|
|
272
|
-
echo "- \`/workflow status\` - Check progress"
|
|
273
|
-
echo "- \`/workflow resume\` - Resume after break"
|