@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,267 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DEPRECATED: Use `pf git branches` instead.
|
|
3
|
+
# This shim forwards to the Python CLI.
|
|
5
4
|
set -e
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if [ -f .env ]; then
|
|
9
|
-
set -a; source .env; set +a
|
|
10
|
-
elif [ -f ../.env ]; then
|
|
11
|
-
set -a; source ../.env; set +a
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
show_help() {
|
|
15
|
-
cat << EOF
|
|
16
|
-
Create Feature Branches - Idempotent branch creation/checkout
|
|
17
|
-
|
|
18
|
-
Usage: ./create-feature-branches.sh <branch-name> [repos]
|
|
19
|
-
|
|
20
|
-
Arguments:
|
|
21
|
-
branch-name Branch name (e.g., feat/11-2-file-preview)
|
|
22
|
-
repos Which repos to branch (default: all)
|
|
23
|
-
Options: api, ui, all
|
|
24
|
-
|
|
25
|
-
Repo Options:
|
|
26
|
-
api - Pennyfarthing-api only
|
|
27
|
-
ui - Pennyfarthing-ui only
|
|
28
|
-
all - both repos (default)
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
# All repos (default)
|
|
32
|
-
./create-feature-branches.sh feat/cross-repo-feature
|
|
33
|
-
|
|
34
|
-
# Pennyfarthing UI only
|
|
35
|
-
./create-feature-branches.sh feat/11-2-ui-component ui
|
|
36
|
-
|
|
37
|
-
# Pennyfarthing API only
|
|
38
|
-
./create-feature-branches.sh fix/validation-bug api
|
|
39
|
-
|
|
40
|
-
Behavior:
|
|
41
|
-
- Idempotent: Checks out existing branches or creates new ones
|
|
42
|
-
- Worktree-aware: Detects main checkout vs worktree
|
|
43
|
-
- Always branches from develop
|
|
44
|
-
- Fetches latest develop before branching
|
|
45
|
-
|
|
46
|
-
EOF
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
|
50
|
-
show_help
|
|
51
|
-
exit 0
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
BRANCH_NAME="$1"
|
|
55
|
-
REPOS="${2:-all}"
|
|
56
|
-
|
|
57
|
-
# Validate repos parameter
|
|
58
|
-
if [[ ! "$REPOS" =~ ^(api|ui|all)$ ]]; then
|
|
59
|
-
echo "❌ Error: repos must be one of: api, ui, all"
|
|
60
|
-
echo " Got: $REPOS"
|
|
61
|
-
echo ""
|
|
62
|
-
echo "Options:"
|
|
63
|
-
echo " api - Pennyfarthing-api only"
|
|
64
|
-
echo " ui - Pennyfarthing-ui only"
|
|
65
|
-
echo " all - both repos (default)"
|
|
66
|
-
exit 1
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# Detect if we're in a worktree
|
|
70
|
-
CURRENT_DIR=$(pwd)
|
|
71
|
-
if [[ "$CURRENT_DIR" == *"/worktrees/"* ]]; then
|
|
72
|
-
# Extract worktree name from path
|
|
73
|
-
WORKTREE_NAME=$(echo "$CURRENT_DIR" | sed -E 's|.*/worktrees/([^/]+).*|\1|')
|
|
74
|
-
REPO_BASE="$PROJECT_ROOT/worktrees/$WORKTREE_NAME"
|
|
75
|
-
echo "📂 Detected worktree: $WORKTREE_NAME"
|
|
76
|
-
else
|
|
77
|
-
REPO_BASE="$PROJECT_ROOT"
|
|
78
|
-
echo "📂 Using main checkout"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# Array to track processed repos for verification
|
|
82
|
-
declare -a PROCESSED_REPOS
|
|
83
|
-
|
|
84
|
-
# Function to create or checkout branch in a repo
|
|
85
|
-
create_or_checkout_branch() {
|
|
86
|
-
local repo_path=$1
|
|
87
|
-
local repo_name=$2
|
|
88
|
-
|
|
89
|
-
if [ ! -d "$repo_path" ]; then
|
|
90
|
-
echo "⚠️ Skipping $repo_name: directory not found at $repo_path"
|
|
91
|
-
return
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
cd "$repo_path"
|
|
95
|
-
|
|
96
|
-
echo ""
|
|
97
|
-
echo "🔧 Processing $repo_name..."
|
|
98
|
-
|
|
99
|
-
# Fetch latest from remote
|
|
100
|
-
echo " Fetching from origin..."
|
|
101
|
-
git fetch origin --quiet
|
|
102
|
-
|
|
103
|
-
# Check if branch exists locally
|
|
104
|
-
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
|
|
105
|
-
echo " ✅ Branch exists locally, checking out: $BRANCH_NAME"
|
|
106
|
-
git checkout "$BRANCH_NAME"
|
|
107
|
-
# Check if branch exists on remote
|
|
108
|
-
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
|
|
109
|
-
echo " ✅ Branch exists on remote, checking out and tracking: $BRANCH_NAME"
|
|
110
|
-
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
|
|
111
|
-
else
|
|
112
|
-
# Branch doesn't exist, create from develop
|
|
113
|
-
echo " 🌿 Creating new branch from develop: $BRANCH_NAME"
|
|
114
|
-
|
|
115
|
-
# Make sure we have latest develop
|
|
116
|
-
git fetch origin develop:develop --quiet 2>/dev/null || true
|
|
117
|
-
|
|
118
|
-
# Checkout develop first
|
|
119
|
-
if git show-ref --verify --quiet "refs/heads/develop"; then
|
|
120
|
-
git checkout develop --quiet
|
|
121
|
-
git pull origin develop --quiet
|
|
122
|
-
else
|
|
123
|
-
echo " ⚠️ Local develop doesn't exist, fetching from remote"
|
|
124
|
-
git fetch origin develop:develop --quiet
|
|
125
|
-
git checkout develop --quiet
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
# Create new branch
|
|
129
|
-
git checkout -b "$BRANCH_NAME"
|
|
130
|
-
echo " ✅ Created: $BRANCH_NAME"
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
# Show current status
|
|
134
|
-
CURRENT_BRANCH=$(git branch --show-current)
|
|
135
|
-
echo " 📍 Now on: $CURRENT_BRANCH"
|
|
136
|
-
|
|
137
|
-
# Track this repo for verification
|
|
138
|
-
PROCESSED_REPOS+=("$repo_path:$repo_name")
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
echo "🌿 Creating/checking out feature branches..."
|
|
142
|
-
echo " Branch: $BRANCH_NAME"
|
|
143
|
-
echo " Repos: $REPOS"
|
|
144
|
-
|
|
145
|
-
# Process repos based on selection
|
|
146
|
-
# When processing multiple repos, run in parallel for faster network I/O
|
|
147
|
-
case "$REPOS" in
|
|
148
|
-
api)
|
|
149
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-api" "Pennyfarthing-api"
|
|
150
|
-
;;
|
|
151
|
-
ui)
|
|
152
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-ui" "Pennyfarthing-ui"
|
|
153
|
-
;;
|
|
154
|
-
all)
|
|
155
|
-
# Parallel execution for both repos
|
|
156
|
-
tmpdir=$(mktemp -d)
|
|
157
|
-
trap "rm -rf '$tmpdir'" EXIT
|
|
158
|
-
HAD_ERRORS=false
|
|
159
|
-
|
|
160
|
-
# Run both in parallel, capturing output
|
|
161
|
-
# Write to separate files to avoid race condition on shared file
|
|
162
|
-
(
|
|
163
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-api" "Pennyfarthing-api"
|
|
164
|
-
echo "$REPO_BASE/Pennyfarthing-api:Pennyfarthing-api" > "$tmpdir/api.processed"
|
|
165
|
-
) > "$tmpdir/api.out" 2>&1 &
|
|
166
|
-
pid_api=$!
|
|
167
|
-
|
|
168
|
-
(
|
|
169
|
-
create_or_checkout_branch "$REPO_BASE/Pennyfarthing-ui" "Pennyfarthing-ui"
|
|
170
|
-
echo "$REPO_BASE/Pennyfarthing-ui:Pennyfarthing-ui" > "$tmpdir/ui.processed"
|
|
171
|
-
) > "$tmpdir/ui.out" 2>&1 &
|
|
172
|
-
pid_ui=$!
|
|
173
|
-
|
|
174
|
-
# Wait for both and capture exit codes
|
|
175
|
-
wait $pid_api; rc_api=$?
|
|
176
|
-
wait $pid_ui; rc_ui=$?
|
|
177
|
-
|
|
178
|
-
# Show output in order
|
|
179
|
-
[ -f "$tmpdir/api.out" ] && cat "$tmpdir/api.out"
|
|
180
|
-
[ -f "$tmpdir/ui.out" ] && cat "$tmpdir/ui.out"
|
|
181
|
-
|
|
182
|
-
# Rebuild PROCESSED_REPOS from separate files (avoids race condition)
|
|
183
|
-
[ -f "$tmpdir/api.processed" ] && PROCESSED_REPOS+=("$(cat "$tmpdir/api.processed")")
|
|
184
|
-
[ -f "$tmpdir/ui.processed" ] && PROCESSED_REPOS+=("$(cat "$tmpdir/ui.processed")")
|
|
185
|
-
|
|
186
|
-
# Check for failures
|
|
187
|
-
if [ $rc_api -ne 0 ] || [ $rc_ui -ne 0 ]; then
|
|
188
|
-
echo "⚠️ Some repos had errors"
|
|
189
|
-
HAD_ERRORS=true
|
|
190
|
-
fi
|
|
191
|
-
;;
|
|
192
|
-
esac
|
|
193
|
-
|
|
194
|
-
echo ""
|
|
195
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
196
|
-
echo "🔍 Verification Summary"
|
|
197
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
198
|
-
|
|
199
|
-
# Verify each processed repo
|
|
200
|
-
for repo_info in "${PROCESSED_REPOS[@]}"; do
|
|
201
|
-
repo_path="${repo_info%%:*}"
|
|
202
|
-
repo_name="${repo_info##*:}"
|
|
203
|
-
|
|
204
|
-
if [ -d "$repo_path" ]; then
|
|
205
|
-
cd "$repo_path"
|
|
206
|
-
|
|
207
|
-
echo ""
|
|
208
|
-
echo "📦 $repo_name"
|
|
209
|
-
echo " Path: $repo_path"
|
|
210
|
-
|
|
211
|
-
# Current branch
|
|
212
|
-
CURRENT_BRANCH=$(git branch --show-current)
|
|
213
|
-
echo " Branch: $CURRENT_BRANCH"
|
|
214
|
-
|
|
215
|
-
# Check if branch matches expected
|
|
216
|
-
if [ "$CURRENT_BRANCH" = "$BRANCH_NAME" ]; then
|
|
217
|
-
echo " ✅ Branch matches: $BRANCH_NAME"
|
|
218
|
-
else
|
|
219
|
-
echo " ⚠️ Branch mismatch! Expected: $BRANCH_NAME, Got: $CURRENT_BRANCH"
|
|
220
|
-
fi
|
|
221
|
-
|
|
222
|
-
# Latest commit
|
|
223
|
-
COMMIT_INFO=$(git log -1 --format="%h - %s" 2>/dev/null)
|
|
224
|
-
echo " Commit: $COMMIT_INFO"
|
|
225
|
-
|
|
226
|
-
# Check remote tracking
|
|
227
|
-
UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "none")
|
|
228
|
-
if [ "$UPSTREAM" != "none" ]; then
|
|
229
|
-
echo " Remote: $UPSTREAM"
|
|
230
|
-
|
|
231
|
-
# Check if up to date with remote
|
|
232
|
-
git fetch origin "$CURRENT_BRANCH" --quiet 2>/dev/null || true
|
|
233
|
-
LOCAL=$(git rev-parse @ 2>/dev/null)
|
|
234
|
-
REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "none")
|
|
235
|
-
|
|
236
|
-
if [ "$LOCAL" = "$REMOTE" ]; then
|
|
237
|
-
echo " Status: ✅ Up to date with remote"
|
|
238
|
-
elif [ "$REMOTE" = "none" ]; then
|
|
239
|
-
echo " Status: ⚠️ No remote branch yet (push needed)"
|
|
240
|
-
else
|
|
241
|
-
BEHIND=$(git rev-list --count HEAD..@{u} 2>/dev/null || echo "0")
|
|
242
|
-
AHEAD=$(git rev-list --count @{u}..HEAD 2>/dev/null || echo "0")
|
|
243
|
-
if [ "$AHEAD" -gt 0 ] && [ "$BEHIND" -gt 0 ]; then
|
|
244
|
-
echo " Status: ⚠️ Diverged ($AHEAD ahead, $BEHIND behind)"
|
|
245
|
-
elif [ "$AHEAD" -gt 0 ]; then
|
|
246
|
-
echo " Status: ⬆️ $AHEAD commit(s) ahead of remote"
|
|
247
|
-
elif [ "$BEHIND" -gt 0 ]; then
|
|
248
|
-
echo " Status: ⬇️ $BEHIND commit(s) behind remote"
|
|
249
|
-
fi
|
|
250
|
-
fi
|
|
251
|
-
else
|
|
252
|
-
echo " Remote: none (local branch only)"
|
|
253
|
-
echo " Status: ⚠️ Not tracking remote (push with -u needed)"
|
|
254
|
-
fi
|
|
255
|
-
fi
|
|
256
|
-
done
|
|
257
|
-
|
|
258
|
-
echo ""
|
|
259
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
260
|
-
if [ "$HAD_ERRORS" = true ]; then
|
|
261
|
-
echo "⚠️ Done with errors. Check output above."
|
|
262
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
263
|
-
exit 1
|
|
264
|
-
else
|
|
265
|
-
echo "✅ Done! All branches verified and ready."
|
|
266
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
267
|
-
fi
|
|
5
|
+
echo "DEPRECATED: create-feature-branches.sh — use 'pf git branches' instead" >&2
|
|
6
|
+
exec pf git branches "$@"
|
|
@@ -1,152 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# Shows: branch, status, unpushed commits for all repos
|
|
6
|
-
# Reads repo configuration from .pennyfarthing/repos.yaml
|
|
7
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DEPRECATED: Use `pf git status` instead.
|
|
3
|
+
# This shim forwards to the Python CLI.
|
|
8
4
|
set -e
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
-
if [ -f "$SCRIPT_DIR/../.env" ]; then
|
|
13
|
-
set -a; source "$SCRIPT_DIR/../.env"; set +a
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
# Fallback if PROJECT_ROOT not set
|
|
17
|
-
PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
|
|
18
|
-
|
|
19
|
-
# Source repo utilities for dynamic repo configuration
|
|
20
|
-
source "$SCRIPT_DIR/../misc/repo-utils.sh"
|
|
21
|
-
|
|
22
|
-
# Colors
|
|
23
|
-
GREEN='\033[0;32m'
|
|
24
|
-
YELLOW='\033[1;33m'
|
|
25
|
-
BLUE='\033[0;34m'
|
|
26
|
-
RED='\033[0;31m'
|
|
27
|
-
NC='\033[0m'
|
|
28
|
-
|
|
29
|
-
BRIEF=false
|
|
30
|
-
if [ "${1:-}" = "--brief" ] || [ "${1:-}" = "-b" ]; then
|
|
31
|
-
BRIEF=true
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
cd "$PROJECT_ROOT"
|
|
35
|
-
|
|
36
|
-
show_repo_status() {
|
|
37
|
-
local repo_name=$1
|
|
38
|
-
local repo_dir=$2 # Note: can't use 'path' - it's a zsh special variable
|
|
39
|
-
|
|
40
|
-
if [ ! -d "$repo_dir/.git" ] && [ ! -d "$repo_dir" ]; then
|
|
41
|
-
return
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
local branch=$(git -C "$repo_dir" branch --show-current 2>/dev/null || echo "detached")
|
|
45
|
-
local git_status=$(git -C "$repo_dir" status --short 2>/dev/null)
|
|
46
|
-
local git_status_count=$(echo "$git_status" | grep -c . 2>/dev/null); git_status_count=${git_status_count:-0}
|
|
47
|
-
local unpushed=$(git -C "$repo_dir" log origin/develop..HEAD --oneline 2>/dev/null | head -5)
|
|
48
|
-
local unpushed_count=$(git -C "$repo_dir" log origin/develop..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
49
|
-
|
|
50
|
-
if $BRIEF; then
|
|
51
|
-
# One-line format
|
|
52
|
-
local status_indicator=""
|
|
53
|
-
[ "$git_status_count" -gt 0 ] && status_indicator="${YELLOW}M${NC}" || status_indicator="${GREEN}✓${NC}"
|
|
54
|
-
local push_indicator=""
|
|
55
|
-
[ "$unpushed_count" -gt 0 ] && push_indicator=" ${BLUE}↑${unpushed_count}${NC}"
|
|
56
|
-
echo -e "$repo_name: $branch $status_indicator$push_indicator"
|
|
57
|
-
else
|
|
58
|
-
echo -e "${BLUE}=== $repo_name ===${NC}"
|
|
59
|
-
echo -e "Branch: ${GREEN}$branch${NC}"
|
|
60
|
-
|
|
61
|
-
if [ -n "$git_status" ]; then
|
|
62
|
-
echo -e "${YELLOW}Changes:${NC}"
|
|
63
|
-
echo "$git_status" | head -10 | sed 's/^/ /'
|
|
64
|
-
[ "$git_status_count" -gt 10 ] && echo " ... and $((git_status_count - 10)) more"
|
|
65
|
-
else
|
|
66
|
-
echo -e "${GREEN}Clean${NC}"
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
if [ "$unpushed_count" -gt 0 ]; then
|
|
70
|
-
echo -e "${BLUE}Unpushed ($unpushed_count):${NC}"
|
|
71
|
-
echo "$unpushed" | sed 's/^/ /'
|
|
72
|
-
[ "$unpushed_count" -gt 5 ] && echo " ... and $((unpushed_count - 5)) more"
|
|
73
|
-
fi
|
|
74
|
-
echo ""
|
|
75
|
-
fi
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if ! $BRIEF; then
|
|
79
|
-
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
80
|
-
echo -e "${BLUE} Git Status - All Repos${NC}"
|
|
81
|
-
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
82
|
-
echo ""
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
# Check each repo from configuration (parallelized for performance)
|
|
86
|
-
repo_count=$(get_repo_count)
|
|
87
|
-
if [[ "$repo_count" -eq 0 ]]; then
|
|
88
|
-
# No repos configured, just show current directory
|
|
89
|
-
show_repo_status "Project" "$PROJECT_ROOT"
|
|
90
|
-
else
|
|
91
|
-
# Create temp dir for parallel output capture
|
|
92
|
-
tmpdir=$(mktemp -d)
|
|
93
|
-
trap "rm -rf '$tmpdir'" EXIT
|
|
94
|
-
|
|
95
|
-
# Launch status checks in parallel
|
|
96
|
-
for repo in $(get_repos); do
|
|
97
|
-
repo_path=$(get_repo_full_path "$repo")
|
|
98
|
-
(show_repo_status "$repo" "$repo_path" > "$tmpdir/$repo.out" 2>&1) &
|
|
99
|
-
done
|
|
100
|
-
wait
|
|
101
|
-
|
|
102
|
-
# Output results in order
|
|
103
|
-
for repo in $(get_repos); do
|
|
104
|
-
[ -f "$tmpdir/$repo.out" ] && cat "$tmpdir/$repo.out"
|
|
105
|
-
done
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
if ! $BRIEF; then
|
|
109
|
-
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
110
|
-
|
|
111
|
-
# Summary
|
|
112
|
-
total_changes=0
|
|
113
|
-
total_unpushed=0
|
|
114
|
-
|
|
115
|
-
if [[ "$repo_count" -eq 0 ]]; then
|
|
116
|
-
# No repos configured, just check current directory
|
|
117
|
-
count=$(git -C "$PROJECT_ROOT" status --short 2>/dev/null | wc -l | tr -d ' ')
|
|
118
|
-
total_changes=$((total_changes + count))
|
|
119
|
-
unpushed=$(git -C "$PROJECT_ROOT" log origin/develop..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
120
|
-
total_unpushed=$((total_unpushed + unpushed))
|
|
121
|
-
else
|
|
122
|
-
# Parallelize summary collection
|
|
123
|
-
summary_tmp=$(mktemp -d)
|
|
124
|
-
for repo in $(get_repos); do
|
|
125
|
-
repo_path=$(get_repo_full_path "$repo")
|
|
126
|
-
(
|
|
127
|
-
[ -d "$repo_path/.git" ] || [ -d "$repo_path" ] || exit 0
|
|
128
|
-
count=$(git -C "$repo_path" status --short 2>/dev/null | wc -l | tr -d ' ')
|
|
129
|
-
unpushed=$(git -C "$repo_path" log origin/develop..HEAD --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
130
|
-
echo "$count $unpushed" > "$summary_tmp/$repo.count"
|
|
131
|
-
) &
|
|
132
|
-
done
|
|
133
|
-
wait
|
|
134
|
-
|
|
135
|
-
# Aggregate results
|
|
136
|
-
for repo in $(get_repos); do
|
|
137
|
-
if [ -f "$summary_tmp/$repo.count" ]; then
|
|
138
|
-
read count unpushed < "$summary_tmp/$repo.count"
|
|
139
|
-
total_changes=$((total_changes + count))
|
|
140
|
-
total_unpushed=$((total_unpushed + unpushed))
|
|
141
|
-
fi
|
|
142
|
-
done
|
|
143
|
-
rm -rf "$summary_tmp"
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
if [ "$total_changes" -eq 0 ] && [ "$total_unpushed" -eq 0 ]; then
|
|
147
|
-
echo -e "${GREEN}✅ All repos clean and pushed${NC}"
|
|
148
|
-
else
|
|
149
|
-
[ "$total_changes" -gt 0 ] && echo -e "${YELLOW}$total_changes uncommitted change(s)${NC}"
|
|
150
|
-
[ "$total_unpushed" -gt 0 ] && echo -e "${BLUE}$total_unpushed unpushed commit(s)${NC}"
|
|
151
|
-
fi
|
|
152
|
-
fi
|
|
5
|
+
echo "DEPRECATED: git-status-all.sh — use 'pf git status' instead" >&2
|
|
6
|
+
exec pf git status "$@"
|
|
@@ -1,144 +1,6 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# End-user projects use `pennyfarthing init` which copies hooks from node_modules.
|
|
8
|
-
# This script creates .d/ directories with symlinks so hook changes in
|
|
9
|
-
# pennyfarthing-dist/ take effect immediately.
|
|
10
|
-
|
|
11
|
-
set -euo pipefail
|
|
12
|
-
|
|
13
|
-
# Self-locate and set up PROJECT_ROOT
|
|
14
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
15
|
-
source "$SCRIPT_DIR/../lib/find-root.sh"
|
|
16
|
-
HOOKS_SOURCE="$PROJECT_ROOT/pennyfarthing-dist/scripts/hooks"
|
|
17
|
-
HOOKS_DEST="$PROJECT_ROOT/.git/hooks"
|
|
18
|
-
|
|
19
|
-
DISPATCHER_MARKER="pennyfarthing-dispatcher"
|
|
20
|
-
PF_PREFIX="10"
|
|
21
|
-
MIGRATED_PREFIX="50"
|
|
22
|
-
|
|
23
|
-
# Check we're in a repo with pennyfarthing-dist (framework or orchestrator)
|
|
24
|
-
if [[ ! -d "$PROJECT_ROOT/pennyfarthing-dist" ]]; then
|
|
25
|
-
echo "Error: This script requires pennyfarthing-dist/ at the project root"
|
|
26
|
-
echo " (framework repo or orchestrator with inlined pennyfarthing/)"
|
|
27
|
-
echo " End-user projects should use: pennyfarthing init"
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
# Check .git exists
|
|
32
|
-
if [[ ! -d "$PROJECT_ROOT/.git" ]]; then
|
|
33
|
-
echo "Error: Not a git repository"
|
|
34
|
-
exit 1
|
|
35
|
-
fi
|
|
36
|
-
|
|
37
|
-
echo "Installing git hooks with .d/ dispatcher pattern..."
|
|
38
|
-
echo " Source: pennyfarthing-dist/scripts/hooks/"
|
|
39
|
-
echo " Dest: .git/hooks/"
|
|
40
|
-
echo ""
|
|
41
|
-
|
|
42
|
-
# Shared dispatcher template — single source of truth
|
|
43
|
-
DISPATCHER_TEMPLATE="$PROJECT_ROOT/pennyfarthing-dist/scripts/hooks/dispatcher-template.sh"
|
|
44
|
-
|
|
45
|
-
if [[ ! -f "$DISPATCHER_TEMPLATE" ]]; then
|
|
46
|
-
echo "Error: dispatcher-template.sh not found at $DISPATCHER_TEMPLATE"
|
|
47
|
-
exit 1
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# Generate a dispatcher script for a given hook name
|
|
51
|
-
generate_dispatcher() {
|
|
52
|
-
local hook_name="$1"
|
|
53
|
-
sed "s/__HOOK_NAME__/${hook_name}/g" "$DISPATCHER_TEMPLATE"
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
# Define hooks to install
|
|
57
|
-
HOOKS=(
|
|
58
|
-
"pre-commit.sh:pre-commit"
|
|
59
|
-
"pre-push.sh:pre-push"
|
|
60
|
-
"post-merge.sh:post-merge"
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
for hook_pair in "${HOOKS[@]}"; do
|
|
64
|
-
source_file="${hook_pair%%:*}"
|
|
65
|
-
dest_name="${hook_pair##*:}"
|
|
66
|
-
|
|
67
|
-
source_path="$HOOKS_SOURCE/$source_file"
|
|
68
|
-
dest_path="$HOOKS_DEST/$dest_name"
|
|
69
|
-
d_dir="$HOOKS_DEST/${dest_name}.d"
|
|
70
|
-
pf_hook_name="${PF_PREFIX}-pennyfarthing-${dest_name}.sh"
|
|
71
|
-
pf_hook_path="${d_dir}/${pf_hook_name}"
|
|
72
|
-
|
|
73
|
-
if [[ ! -f "$source_path" ]]; then
|
|
74
|
-
echo " SKIP $dest_name (source not found)"
|
|
75
|
-
continue
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
# Create .d/ directory
|
|
79
|
-
mkdir -p "$d_dir"
|
|
80
|
-
|
|
81
|
-
# Handle existing hook at the dest path
|
|
82
|
-
if [[ -e "$dest_path" ]]; then
|
|
83
|
-
if [[ -f "$dest_path" ]] && grep -q "$DISPATCHER_MARKER" "$dest_path" 2>/dev/null; then
|
|
84
|
-
echo " OK $dest_name dispatcher (already installed)"
|
|
85
|
-
elif [[ -L "$dest_path" ]]; then
|
|
86
|
-
# Old-style symlink — migrate to .d/ pattern
|
|
87
|
-
rm "$dest_path"
|
|
88
|
-
generate_dispatcher "$dest_name" > "$dest_path"
|
|
89
|
-
chmod 755 "$dest_path"
|
|
90
|
-
echo " UPD $dest_name → dispatcher"
|
|
91
|
-
elif [[ -f "$dest_path" ]]; then
|
|
92
|
-
existing_content="$(cat "$dest_path")"
|
|
93
|
-
if echo "$existing_content" | grep -q "pennyfarthing"; then
|
|
94
|
-
# Old pennyfarthing single-file hook — replace with dispatcher
|
|
95
|
-
generate_dispatcher "$dest_name" > "$dest_path"
|
|
96
|
-
chmod 755 "$dest_path"
|
|
97
|
-
echo " UPD $dest_name → dispatcher (was single-file pf hook)"
|
|
98
|
-
else
|
|
99
|
-
# Non-pennyfarthing hook — migrate into .d/
|
|
100
|
-
migrated_name="${MIGRATED_PREFIX}-migrated-${dest_name}.sh"
|
|
101
|
-
migrated_path="${d_dir}/${migrated_name}"
|
|
102
|
-
if [[ ! -f "$migrated_path" ]]; then
|
|
103
|
-
mv "$dest_path" "$migrated_path"
|
|
104
|
-
chmod 755 "$migrated_path"
|
|
105
|
-
echo " MIG $dest_name → ${dest_name}.d/${migrated_name}"
|
|
106
|
-
fi
|
|
107
|
-
generate_dispatcher "$dest_name" > "$dest_path"
|
|
108
|
-
chmod 755 "$dest_path"
|
|
109
|
-
echo " NEW $dest_name dispatcher"
|
|
110
|
-
fi
|
|
111
|
-
fi
|
|
112
|
-
else
|
|
113
|
-
# No existing hook — install fresh dispatcher
|
|
114
|
-
generate_dispatcher "$dest_name" > "$dest_path"
|
|
115
|
-
chmod 755 "$dest_path"
|
|
116
|
-
echo " NEW $dest_name dispatcher"
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# Symlink pennyfarthing hook into .d/ (framework dev — symlink for live edits)
|
|
120
|
-
# From .git/hooks/{hook}.d/ we need ../../.../pennyfarthing-dist/scripts/hooks/
|
|
121
|
-
relative_path="../../../pennyfarthing-dist/scripts/hooks/$source_file"
|
|
122
|
-
|
|
123
|
-
if [[ -L "$pf_hook_path" ]]; then
|
|
124
|
-
current_target=$(readlink "$pf_hook_path")
|
|
125
|
-
if [[ "$current_target" == "$relative_path" ]]; then
|
|
126
|
-
echo " OK ${dest_name}.d/${pf_hook_name} (already linked)"
|
|
127
|
-
else
|
|
128
|
-
rm "$pf_hook_path"
|
|
129
|
-
ln -sf "$relative_path" "$pf_hook_path"
|
|
130
|
-
echo " UPD ${dest_name}.d/${pf_hook_name} → $relative_path"
|
|
131
|
-
fi
|
|
132
|
-
elif [[ -f "$pf_hook_path" ]]; then
|
|
133
|
-
# Regular file — replace with symlink for dev
|
|
134
|
-
rm "$pf_hook_path"
|
|
135
|
-
ln -sf "$relative_path" "$pf_hook_path"
|
|
136
|
-
echo " UPD ${dest_name}.d/${pf_hook_name} → $relative_path (was copy)"
|
|
137
|
-
else
|
|
138
|
-
ln -sf "$relative_path" "$pf_hook_path"
|
|
139
|
-
echo " NEW ${dest_name}.d/${pf_hook_name} → $relative_path"
|
|
140
|
-
fi
|
|
141
|
-
done
|
|
142
|
-
|
|
143
|
-
echo ""
|
|
144
|
-
echo "Done. Verify with: ls -la .git/hooks/*.d/"
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DEPRECATED: Use `pf git install-hooks` instead.
|
|
3
|
+
# This shim forwards to the Python CLI.
|
|
4
|
+
set -e
|
|
5
|
+
echo "DEPRECATED: install-git-hooks.sh — use 'pf git install-hooks' instead" >&2
|
|
6
|
+
exec pf git install-hooks "$@"
|