@pipemd-core/pipemd 1.0.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/AI_SETUP_PIPEMD.md +184 -0
- package/CHANGELOG.md +47 -0
- package/LICENSE +15 -0
- package/README.md +535 -0
- package/dist/index.js +6647 -0
- package/dist/plugins/opencode-server.js +235 -0
- package/dist/plugins/opencode-tui.js +914 -0
- package/dist/templates/agent-decision-tree.md +113 -0
- package/dist/templates/static-rules.md +7 -0
- package/package.json +68 -0
- package/scripts/C-CPP/architecture/arch.sh +229 -0
- package/scripts/C-CPP/lib/limit.sh +146 -0
- package/scripts/C-CPP/project/class-diagram.sh +96 -0
- package/scripts/C-CPP/project/cmake-targets.sh +68 -0
- package/scripts/C-CPP/project/deps.sh +44 -0
- package/scripts/C-CPP/project/find-todos.sh +6 -0
- package/scripts/C-CPP/project/include-graph.sh +110 -0
- package/scripts/C-CPP/project/interfaces.sh +108 -0
- package/scripts/C-CPP/project/tree.sh +5 -0
- package/scripts/C-CPP/quality/lint.sh +14 -0
- package/scripts/C-CPP/quality/test-summary.sh +22 -0
- package/scripts/C-CPP/quality/type-check.sh +26 -0
- package/scripts/DevOps/architecture/arch.sh +186 -0
- package/scripts/DevOps/devops/aws-context.sh +34 -0
- package/scripts/DevOps/devops/docker-stats.sh +42 -0
- package/scripts/DevOps/devops/k8s-unhealthy.sh +41 -0
- package/scripts/DevOps/devops/tf-state.sh +65 -0
- package/scripts/DevOps/lib/limit.sh +143 -0
- package/scripts/Generic/architecture/arch.sh +570 -0
- package/scripts/Generic/lib/limit.sh +140 -0
- package/scripts/Go/architecture/arch.sh +79 -0
- package/scripts/Go/lib/limit.sh +142 -0
- package/scripts/Go/project/deps.sh +35 -0
- package/scripts/Go/project/find-todos.sh +6 -0
- package/scripts/Go/project/go-interfaces.sh +18 -0
- package/scripts/Go/project/go-packages.sh +28 -0
- package/scripts/Go/project/tree.sh +5 -0
- package/scripts/Go/quality/lint.sh +16 -0
- package/scripts/Go/quality/test-summary.sh +16 -0
- package/scripts/Go/quality/type-check.sh +16 -0
- package/scripts/Node-TypeScript/api/express-routes.sh +14 -0
- package/scripts/Node-TypeScript/api/nest-controllers.sh +18 -0
- package/scripts/Node-TypeScript/architecture/arch.sh +174 -0
- package/scripts/Node-TypeScript/frontend/angular-routes.sh +15 -0
- package/scripts/Node-TypeScript/frontend/nextjs-app-router.sh +13 -0
- package/scripts/Node-TypeScript/frontend/react-components.sh +20 -0
- package/scripts/Node-TypeScript/lib/limit.sh +146 -0
- package/scripts/Node-TypeScript/project/deps.sh +15 -0
- package/scripts/Node-TypeScript/project/find-todos.sh +6 -0
- package/scripts/Node-TypeScript/quality/lint.sh +10 -0
- package/scripts/Node-TypeScript/quality/test-summary.sh +39 -0
- package/scripts/Node-TypeScript/quality/type-check.sh +10 -0
- package/scripts/Python/api/fastapi-routes.sh +12 -0
- package/scripts/Python/architecture/arch.sh +220 -0
- package/scripts/Python/db/django-models.sh +12 -0
- package/scripts/Python/db/sqlalchemy.sh +17 -0
- package/scripts/Python/lib/limit.sh +144 -0
- package/scripts/Python/project/deps.sh +28 -0
- package/scripts/Python/project/find-todos.sh +6 -0
- package/scripts/Python/quality/lint.sh +13 -0
- package/scripts/Python/quality/test-summary.sh +11 -0
- package/scripts/Python/quality/type-check.sh +10 -0
- package/scripts/Rust/architecture/arch.sh +176 -0
- package/scripts/Rust/lib/limit.sh +142 -0
- package/scripts/Rust/project/cargo-deps.sh +42 -0
- package/scripts/Rust/project/cargo-features.sh +26 -0
- package/scripts/Rust/project/find-todos.sh +6 -0
- package/scripts/Rust/project/tree.sh +5 -0
- package/scripts/Rust/quality/lint.sh +16 -0
- package/scripts/Rust/quality/test-summary.sh +16 -0
- package/scripts/Rust/quality/type-check.sh +16 -0
- package/scripts/Shared/api/express-routes.sh +11 -0
- package/scripts/Shared/api/fastapi-routes.sh +10 -0
- package/scripts/Shared/api/nest-controllers.sh +22 -0
- package/scripts/Shared/architecture/normalize.sh +178 -0
- package/scripts/Shared/crew/crew.sh +15 -0
- package/scripts/Shared/db/django-models.sh +11 -0
- package/scripts/Shared/db/prisma.sh +33 -0
- package/scripts/Shared/db/sqlalchemy.sh +12 -0
- package/scripts/Shared/frontend/angular-routes.sh +11 -0
- package/scripts/Shared/frontend/nextjs-app-router.sh +13 -0
- package/scripts/Shared/frontend/react-components.sh +11 -0
- package/scripts/Shared/git/diff-stat.sh +6 -0
- package/scripts/Shared/git/git-branch.sh +16 -0
- package/scripts/Shared/git/git-log.sh +6 -0
- package/scripts/Shared/git/git-status.sh +6 -0
- package/scripts/Shared/lib/limit.sh +144 -0
- package/scripts/Shared/project/compose-md.sh +182 -0
- package/scripts/Shared/project/deps.sh +69 -0
- package/scripts/Shared/project/find-todos.sh +6 -0
- package/scripts/Shared/project/tree.sh +5 -0
- package/scripts/Shared/quality/lint.sh +81 -0
- package/scripts/Shared/quality/test-summary.sh +103 -0
- package/scripts/Shared/quality/type-check.sh +114 -0
- package/scripts/copy-plugins.mjs +4 -0
- package/scripts/copy-templates.mjs +5 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# limit.sh — Smart output limiter with compact fallbacks
|
|
4
|
+
# TOKEN profile multiplier (override via PMD_TOKEN_PROFILE env var)
|
|
5
|
+
PMD_TOKEN_PROFILE="${PMD_TOKEN_PROFILE:-medium}"
|
|
6
|
+
case "$PMD_TOKEN_PROFILE" in
|
|
7
|
+
low) MULT_NUM=1; MULT_DEN=2 ;;
|
|
8
|
+
medium) MULT_NUM=1; MULT_DEN=1 ;;
|
|
9
|
+
high) MULT_NUM=3; MULT_DEN=2 ;;
|
|
10
|
+
xhigh) MULT_NUM=2; MULT_DEN=1 ;;
|
|
11
|
+
unlimited) PMD_UNLIMITED=1 ;;
|
|
12
|
+
*) MULT_NUM=1; MULT_DEN=1 ;;
|
|
13
|
+
esac
|
|
14
|
+
|
|
15
|
+
# Token budget constants (override via PMD_MAX_* env vars, scaled by profile)
|
|
16
|
+
if [ "${PMD_UNLIMITED:-0}" = "1" ]; then
|
|
17
|
+
MAX_TREE=${PMD_MAX_TREE:-99999}
|
|
18
|
+
MAX_DEPS=${PMD_MAX_DEPS:-99999}
|
|
19
|
+
MAX_TODOS=${PMD_MAX_TODOS:-99999}
|
|
20
|
+
MAX_LOG=${PMD_MAX_LOG:-99999}
|
|
21
|
+
MAX_BRANCH=${PMD_MAX_BRANCH:-99999}
|
|
22
|
+
MAX_STATUS=${PMD_MAX_STATUS:-99999}
|
|
23
|
+
MAX_DIFF=${PMD_MAX_DIFF:-99999}
|
|
24
|
+
MAX_TYPECHECK=${PMD_MAX_TYPECHECK:-99999}
|
|
25
|
+
MAX_LINT=${PMD_MAX_LINT:-99999}
|
|
26
|
+
MAX_TEST=${PMD_MAX_TEST:-99999}
|
|
27
|
+
MAX_PRISMA=${PMD_MAX_PRISMA:-99999}
|
|
28
|
+
MAX_EXPRESS=${PMD_MAX_EXPRESS:-99999}
|
|
29
|
+
MAX_FASTAPI=${PMD_MAX_FASTAPI:-99999}
|
|
30
|
+
MAX_DJANGO=${PMD_MAX_DJANGO:-99999}
|
|
31
|
+
MAX_SQLALCHEMY=${PMD_MAX_SQLALCHEMY:-99999}
|
|
32
|
+
MAX_NEST=${PMD_MAX_NEST:-99999}
|
|
33
|
+
MAX_NEXTJS=${PMD_MAX_NEXTJS:-99999}
|
|
34
|
+
MAX_REACT=${PMD_MAX_REACT:-99999}
|
|
35
|
+
MAX_ANGULAR=${PMD_MAX_ANGULAR:-99999}
|
|
36
|
+
MAX_CMAKE=${PMD_MAX_CMAKE:-99999}
|
|
37
|
+
MAX_CLASS=${PMD_MAX_CLASS:-99999}
|
|
38
|
+
MAX_INTERFACE=${PMD_MAX_INTERFACE:-99999}
|
|
39
|
+
MAX_INCLUDE=${PMD_MAX_INCLUDE:-99999}
|
|
40
|
+
MAX_CARGO=${PMD_MAX_CARGO:-99999}
|
|
41
|
+
MAX_GO_PKGS=${PMD_MAX_GO_PKGS:-99999}
|
|
42
|
+
MAX_CARGO_FEATURES=${PMD_MAX_CARGO_FEATURES:-99999}
|
|
43
|
+
MAX_GO_INTERFACES=${PMD_MAX_GO_INTERFACES:-99999}
|
|
44
|
+
MAX_DOCKER=${PMD_MAX_DOCKER:-99999}
|
|
45
|
+
MAX_K8S=${PMD_MAX_K8S:-99999}
|
|
46
|
+
MAX_TF=${PMD_MAX_TF:-99999}
|
|
47
|
+
MAX_AWS=${PMD_MAX_AWS:-99999}
|
|
48
|
+
MAX_ARCH=${PMD_MAX_ARCH:-99999}
|
|
49
|
+
MAX_COMPOSE=${PMD_MAX_COMPOSE:-99999}
|
|
50
|
+
MAX_CREW=${PMD_MAX_CREW:-99999}
|
|
51
|
+
else
|
|
52
|
+
MAX_TREE=$(( (${PMD_MAX_TREE:-50} * MULT_NUM) / MULT_DEN ))
|
|
53
|
+
MAX_DEPS=$(( (${PMD_MAX_DEPS:-40} * MULT_NUM) / MULT_DEN ))
|
|
54
|
+
MAX_TODOS=$(( (${PMD_MAX_TODOS:-20} * MULT_NUM) / MULT_DEN ))
|
|
55
|
+
MAX_LOG=$(( (${PMD_MAX_LOG:-20} * MULT_NUM) / MULT_DEN ))
|
|
56
|
+
MAX_BRANCH=$(( (${PMD_MAX_BRANCH:-20} * MULT_NUM) / MULT_DEN ))
|
|
57
|
+
MAX_STATUS=$(( (${PMD_MAX_STATUS:-30} * MULT_NUM) / MULT_DEN ))
|
|
58
|
+
MAX_DIFF=$(( (${PMD_MAX_DIFF:-30} * MULT_NUM) / MULT_DEN ))
|
|
59
|
+
MAX_TYPECHECK=$(( (${PMD_MAX_TYPECHECK:-30} * MULT_NUM) / MULT_DEN ))
|
|
60
|
+
MAX_LINT=$(( (${PMD_MAX_LINT:-20} * MULT_NUM) / MULT_DEN ))
|
|
61
|
+
MAX_TEST=$(( (${PMD_MAX_TEST:-10} * MULT_NUM) / MULT_DEN ))
|
|
62
|
+
MAX_PRISMA=$(( (${PMD_MAX_PRISMA:-40} * MULT_NUM) / MULT_DEN ))
|
|
63
|
+
MAX_EXPRESS=$(( (${PMD_MAX_EXPRESS:-30} * MULT_NUM) / MULT_DEN ))
|
|
64
|
+
MAX_FASTAPI=$(( (${PMD_MAX_FASTAPI:-30} * MULT_NUM) / MULT_DEN ))
|
|
65
|
+
MAX_DJANGO=$(( (${PMD_MAX_DJANGO:-40} * MULT_NUM) / MULT_DEN ))
|
|
66
|
+
MAX_SQLALCHEMY=$(( (${PMD_MAX_SQLALCHEMY:-40} * MULT_NUM) / MULT_DEN ))
|
|
67
|
+
MAX_NEST=$(( (${PMD_MAX_NEST:-30} * MULT_NUM) / MULT_DEN ))
|
|
68
|
+
MAX_NEXTJS=$(( (${PMD_MAX_NEXTJS:-30} * MULT_NUM) / MULT_DEN ))
|
|
69
|
+
MAX_REACT=$(( (${PMD_MAX_REACT:-30} * MULT_NUM) / MULT_DEN ))
|
|
70
|
+
MAX_ANGULAR=$(( (${PMD_MAX_ANGULAR:-30} * MULT_NUM) / MULT_DEN ))
|
|
71
|
+
MAX_CMAKE=$(( (${PMD_MAX_CMAKE:-40} * MULT_NUM) / MULT_DEN ))
|
|
72
|
+
MAX_CLASS=$(( (${PMD_MAX_CLASS:-40} * MULT_NUM) / MULT_DEN ))
|
|
73
|
+
MAX_INTERFACE=$(( (${PMD_MAX_INTERFACE:-30} * MULT_NUM) / MULT_DEN ))
|
|
74
|
+
MAX_INCLUDE=$(( (${PMD_MAX_INCLUDE:-40} * MULT_NUM) / MULT_DEN ))
|
|
75
|
+
MAX_CARGO=$(( (${PMD_MAX_CARGO:-40} * MULT_NUM) / MULT_DEN ))
|
|
76
|
+
MAX_GO_PKGS=$(( (${PMD_MAX_GO_PKGS:-40} * MULT_NUM) / MULT_DEN ))
|
|
77
|
+
MAX_CARGO_FEATURES=$(( (${PMD_MAX_CARGO_FEATURES:-20} * MULT_NUM) / MULT_DEN ))
|
|
78
|
+
MAX_GO_INTERFACES=$(( (${PMD_MAX_GO_INTERFACES:-30} * MULT_NUM) / MULT_DEN ))
|
|
79
|
+
MAX_DOCKER=$(( (${PMD_MAX_DOCKER:-30} * MULT_NUM) / MULT_DEN ))
|
|
80
|
+
MAX_K8S=$(( (${PMD_MAX_K8S:-20} * MULT_NUM) / MULT_DEN ))
|
|
81
|
+
MAX_TF=$(( (${PMD_MAX_TF:-40} * MULT_NUM) / MULT_DEN ))
|
|
82
|
+
MAX_AWS=$(( (${PMD_MAX_AWS:-10} * MULT_NUM) / MULT_DEN ))
|
|
83
|
+
MAX_ARCH=$(( (${PMD_MAX_ARCH:-100} * MULT_NUM) / MULT_DEN ))
|
|
84
|
+
MAX_COMPOSE=$(( (${PMD_MAX_COMPOSE:-150} * MULT_NUM) / MULT_DEN ))
|
|
85
|
+
MAX_CREW=$(( (${PMD_MAX_CREW:-40} * MULT_NUM) / MULT_DEN ))
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
TREE_EXCLUDES="${PMD_TREE_EXCLUDES:-target|.git|.pipemd|node_modules|cargo-registry}"
|
|
89
|
+
|
|
90
|
+
limit_output() {
|
|
91
|
+
local text="$1"
|
|
92
|
+
local max="${2:-25}"
|
|
93
|
+
local fallback="$3"
|
|
94
|
+
local lines
|
|
95
|
+
lines=$(echo "$text" | wc -l)
|
|
96
|
+
if [ "$lines" -le "$max" ]; then
|
|
97
|
+
echo "$text"
|
|
98
|
+
else
|
|
99
|
+
echo "$fallback"
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
limit_tree() {
|
|
104
|
+
local max="${1:-$MAX_TREE}"
|
|
105
|
+
local excl="${TREE_EXCLUDES}"
|
|
106
|
+
|
|
107
|
+
if command -v tree &>/dev/null; then
|
|
108
|
+
local out3
|
|
109
|
+
out3=$(tree -L 3 -I "$excl" --dirsfirst 2>/dev/null)
|
|
110
|
+
local lines3=$(echo "$out3" | wc -l)
|
|
111
|
+
|
|
112
|
+
if [ "$lines3" -le "$max" ]; then
|
|
113
|
+
echo "$out3"
|
|
114
|
+
return
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
local out2
|
|
118
|
+
out2=$(tree -L 2 -I "$excl" --dirsfirst 2>/dev/null)
|
|
119
|
+
local lines2=$(echo "$out2" | wc -l)
|
|
120
|
+
|
|
121
|
+
if [ "$lines2" -le "$max" ]; then
|
|
122
|
+
echo "$out2"
|
|
123
|
+
echo "(${lines3} lines at depth 3, showing depth 2)"
|
|
124
|
+
return
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
local out1
|
|
128
|
+
out1=$(tree -L 1 -I "$excl" --dirsfirst 2>/dev/null)
|
|
129
|
+
echo "$out1"
|
|
130
|
+
echo "(${lines3} lines at depth 3, showing depth 1)"
|
|
131
|
+
else
|
|
132
|
+
echo "Project structure:"
|
|
133
|
+
find . -maxdepth 3 \
|
|
134
|
+
-not -path '*/target/*' \
|
|
135
|
+
-not -path '*/.git/*' \
|
|
136
|
+
-not -path '*/.pipemd/*' \
|
|
137
|
+
-not -name 'target' \
|
|
138
|
+
-not -name '.git' \
|
|
139
|
+
-not -name '.pipemd' \
|
|
140
|
+
2>/dev/null | head -"$max" | sort
|
|
141
|
+
fi
|
|
142
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Cargo dependencies — parse Cargo.toml [dependencies]
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
|
|
6
|
+
if [ ! -f Cargo.toml ]; then
|
|
7
|
+
echo "No Cargo.toml found"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
out=$(awk '
|
|
12
|
+
/^\[dependencies\]/ { in_deps=1; next }
|
|
13
|
+
/^\[/ { in_deps=0 }
|
|
14
|
+
in_deps && /^[a-zA-Z_-]/ {
|
|
15
|
+
gsub(/=.*/, "")
|
|
16
|
+
gsub(/[^a-zA-Z0-9_-]/, "")
|
|
17
|
+
if (length($0) > 0) print $0
|
|
18
|
+
}
|
|
19
|
+
' Cargo.toml 2>/dev/null | head -"$MAX_DEPS")
|
|
20
|
+
|
|
21
|
+
if [ -z "$out" ]; then
|
|
22
|
+
echo "No dependencies found in Cargo.toml"
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
echo "$out"
|
|
27
|
+
|
|
28
|
+
dev_out=$(awk '
|
|
29
|
+
/^\[dev-dependencies\]/ { in_dev=1; next }
|
|
30
|
+
/^\[/ { in_dev=0 }
|
|
31
|
+
in_dev && /^[a-zA-Z_-]/ {
|
|
32
|
+
gsub(/=.*/, "")
|
|
33
|
+
gsub(/[^a-zA-Z0-9_-]/, "")
|
|
34
|
+
if (length($0) > 0) print $0
|
|
35
|
+
}
|
|
36
|
+
' Cargo.toml 2>/dev/null | head -10)
|
|
37
|
+
|
|
38
|
+
if [ -n "$dev_out" ]; then
|
|
39
|
+
echo ""
|
|
40
|
+
echo "Dev dependencies:"
|
|
41
|
+
echo "$dev_out"
|
|
42
|
+
fi
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Cargo feature flags — parse [features] from Cargo.toml
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
|
|
6
|
+
if [ ! -f Cargo.toml ]; then
|
|
7
|
+
echo "No Cargo.toml found"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
out=$(awk '
|
|
12
|
+
/^\[features\]/ { in_features=1; next }
|
|
13
|
+
/^\[/ { in_features=0 }
|
|
14
|
+
in_features && /=/ {
|
|
15
|
+
gsub(/ = .*/, "")
|
|
16
|
+
gsub(/[^a-zA-Z0-9_-]/, "")
|
|
17
|
+
if (length($0) > 0) print $0
|
|
18
|
+
}
|
|
19
|
+
' Cargo.toml 2>/dev/null)
|
|
20
|
+
|
|
21
|
+
if [ -z "$out" ]; then
|
|
22
|
+
echo "No features defined in Cargo.toml"
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
limit_output "$out" "$MAX_CARGO_FEATURES" "$(echo "$out" | head -5 && echo '... more features')"
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Find TODO, FIXME, HACK in Rust source files
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(grep -rn --include="*.rs" 'TODO\|FIXME\|HACK\|XXX\|UNSAFE' . 2>/dev/null | grep -v '/.git/' | grep -v '/.pipemd/' | grep -v '/target/')
|
|
6
|
+
limit_output "$out" "$MAX_TODOS" "$(echo "$out" | head -3 && echo "... and $(($(echo "$out" | wc -l) - 3)) more items")"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Rust lint — cargo clippy
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
|
|
6
|
+
if ! command -v cargo &>/dev/null; then
|
|
7
|
+
echo "cargo not found"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
out=$(cargo clippy --message-format=short 2>&1 | grep -E '^(error|warning)\[' | head -30)
|
|
12
|
+
if [ -z "$out" ]; then
|
|
13
|
+
echo "No clippy warnings"
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
limit_output "$out" "$MAX_LINT" "$(echo "$out" | head -3 && echo '... more clippy warnings')"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Rust test summary — cargo test
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
|
|
6
|
+
if ! command -v cargo &>/dev/null; then
|
|
7
|
+
echo "cargo not found"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
out=$(cargo test 2>&1 | tail -5)
|
|
12
|
+
if [ -z "$out" ]; then
|
|
13
|
+
echo "No test results"
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
echo "$out"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Rust type check — cargo check
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
|
|
6
|
+
if ! command -v cargo &>/dev/null; then
|
|
7
|
+
echo "cargo not found"
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
out=$(cargo check 2>&1 | grep -E '^error' | head -20)
|
|
12
|
+
if [ -z "$out" ]; then
|
|
13
|
+
echo "No type errors"
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
limit_output "$out" "$MAX_TYPECHECK" "$(echo "$out" | head -5 && echo '... more type errors')"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Express route metadata — method + path signatures
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(grep -rn --include='*.js' --include='*.ts' --include='*.mjs' \
|
|
6
|
+
-E '(app|router)\.(get|post|put|delete|patch|all)\(' \
|
|
7
|
+
. 2>/dev/null | grep -v 'node_modules' \
|
|
8
|
+
| sed -E 's/.*\.(get|post|put|delete|patch|all)\([[:space:]]*['\''"](\/[^'\''"]*)['\''"].*/\U\1 \2/' \
|
|
9
|
+
| head -"$MAX_EXPRESS")
|
|
10
|
+
[ -z "$out" ] && echo "No Express routes found" && exit 0
|
|
11
|
+
echo "$out"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# FastAPI route metadata — endpoint signatures
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(grep -rn --include='*.py' '@\(app\|router\)\.\(get\|post\|put\|delete\|patch\)' . 2>/dev/null \
|
|
6
|
+
| grep -v '/__pycache__/' | grep -v '/.venv/' | grep -v '/venv/' \
|
|
7
|
+
| sed -E 's/.*@\w+\.(get|post|put|delete|patch)\([[:space:]]*['\''"](\/[^'\''"]*)['\''"].*/\U\1 \2/' \
|
|
8
|
+
| head -"$MAX_FASTAPI")
|
|
9
|
+
[ -z "$out" ] && echo "No FastAPI routes detected" && exit 0
|
|
10
|
+
echo "$out"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# NestJS controller metadata — auto-detect if NestJS is present
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
if [ ! -d src ]; then
|
|
6
|
+
echo "No NestJS controllers detected"
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
files=$(grep -rl --include='*.ts' '@Controller\|@Get\|@Post\|@Put\|@Delete\|@Patch' src/ 2>/dev/null | grep -v '/node_modules/' | head -10)
|
|
10
|
+
[ -z "$files" ] && echo "No NestJS controllers found" && exit 0
|
|
11
|
+
|
|
12
|
+
echo "$files" | while IFS= read -r f; do
|
|
13
|
+
[ -z "$f" ] && continue
|
|
14
|
+
controller=$(grep -E '@Controller\s*\(\s*['\''"](\/[^'\''"]*)' "$f" 2>/dev/null | sed -E "s/@Controller\s*\(\s*['\"]//;s/['\"].*//")
|
|
15
|
+
methods=$(grep -E '@(Get|Post|Put|Delete|Patch)\s*\(\s*['\''"](\/[^'\''"]*)' "$f" 2>/dev/null | sed -E "s/@(Get|Post|Put|Delete|Patch)\s*\(\s*['\"]//;s/['\"].*//")
|
|
16
|
+
if [ -n "$controller" ]; then
|
|
17
|
+
echo "Controller: $controller"
|
|
18
|
+
echo "$methods" | while IFS= read -r m; do
|
|
19
|
+
[ -n "$m" ] && echo " $m"
|
|
20
|
+
done
|
|
21
|
+
fi
|
|
22
|
+
done | head -"$MAX_NEST"
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Architecture normalizer — TSV edge-list → Mermaid graph TD
|
|
4
|
+
# Input: TSV on stdin (source<TAB>target, ext: prefix marks external deps)
|
|
5
|
+
# Output: Mermaid graph TD with subgraphs, ranked external deps, line budget
|
|
6
|
+
# Env: MAX_ARCH (default 100), MAX_EXT (default 8)
|
|
7
|
+
|
|
8
|
+
: "${MAX_ARCH:=100}"
|
|
9
|
+
: "${MAX_EXT:=8}"
|
|
10
|
+
|
|
11
|
+
awk -v max_arch="$MAX_ARCH" -v max_ext="$MAX_EXT" '
|
|
12
|
+
function safe_id(s) {
|
|
13
|
+
gsub(/[^a-zA-Z0-9]/, "_", s)
|
|
14
|
+
return s
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function clean_label(s) {
|
|
18
|
+
gsub(/^src\//, "", s)
|
|
19
|
+
gsub(/^lib\//, "", s)
|
|
20
|
+
gsub(/^app\//, "", s)
|
|
21
|
+
gsub(/^cmd\//, "", s)
|
|
22
|
+
gsub(/^internal\//, "", s)
|
|
23
|
+
gsub(/^pkg\//, "", s)
|
|
24
|
+
gsub(/^\(root\)$/, "main", s)
|
|
25
|
+
return s
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function group_of(s, n, parts) {
|
|
29
|
+
n = split(s, parts, "/")
|
|
30
|
+
return (n > 1) ? parts[1] : ""
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
BEGIN {
|
|
34
|
+
FS = "\t"
|
|
35
|
+
ne = 0; ni = 0; nx = 0; ng = 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
{
|
|
39
|
+
s = $1; d = $2
|
|
40
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, s)
|
|
41
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, d)
|
|
42
|
+
if (s == "" || d == "" || s == d) next
|
|
43
|
+
|
|
44
|
+
key = s SUBSEP d
|
|
45
|
+
if (key in seen) next
|
|
46
|
+
seen[key] = 1
|
|
47
|
+
ne++
|
|
48
|
+
esrc[ne] = s; edst[ne] = d
|
|
49
|
+
|
|
50
|
+
if (s ~ /^ext:/) {
|
|
51
|
+
n = substr(s, 5)
|
|
52
|
+
if (!(n in exti)) { nx++; exti[n] = nx; extn[nx] = n }
|
|
53
|
+
extdeg[n]++
|
|
54
|
+
} else {
|
|
55
|
+
if (!(s in inti)) { ni++; inti[s] = ni; intn[ni] = s }
|
|
56
|
+
g = group_of(s)
|
|
57
|
+
if (g != "" && !(g in grpi)) { ng++; grp_order[ng] = g; grpi[g] = 1 }
|
|
58
|
+
igrp[s] = g
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (d ~ /^ext:/) {
|
|
62
|
+
n = substr(d, 5)
|
|
63
|
+
if (!(n in exti)) { nx++; exti[n] = nx; extn[nx] = n }
|
|
64
|
+
extdeg[n]++
|
|
65
|
+
} else {
|
|
66
|
+
if (!(d in inti)) { ni++; inti[d] = ni; intn[ni] = d }
|
|
67
|
+
g = group_of(d)
|
|
68
|
+
if (g != "" && !(g in grpi)) { ng++; grp_order[ng] = g; grpi[g] = 1 }
|
|
69
|
+
igrp[d] = g
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
END {
|
|
74
|
+
if (ni == 0) {
|
|
75
|
+
print "No modules found"
|
|
76
|
+
exit 0
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Sort external deps by in-degree (descending)
|
|
80
|
+
for (i = 1; i <= nx; i++) {
|
|
81
|
+
for (j = i + 1; j <= nx; j++) {
|
|
82
|
+
if (extdeg[extn[j]] > extdeg[extn[i]]) {
|
|
83
|
+
tmp = extn[i]; extn[i] = extn[j]; extn[j] = tmp
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Determine how many external deps to show
|
|
89
|
+
n_show_ext = (nx > max_ext) ? max_ext : nx
|
|
90
|
+
for (i = 1; i <= n_show_ext; i++) show_ext[extn[i]] = 1
|
|
91
|
+
|
|
92
|
+
# Count edges that will be shown
|
|
93
|
+
shown_edges = 0
|
|
94
|
+
for (i = 1; i <= ne; i++) {
|
|
95
|
+
s = esrc[i]; d = edst[i]
|
|
96
|
+
if (s ~ /^ext:/) { n = substr(s, 5); if (!(n in show_ext)) continue }
|
|
97
|
+
if (d ~ /^ext:/) { n = substr(d, 5); if (!(n in show_ext)) continue }
|
|
98
|
+
shown_edges++
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Estimate total lines for budget check
|
|
102
|
+
est = 2 + ng * 2 + ni + (n_show_ext > 0 ? 2 + n_show_ext : 0) + shown_edges + 1
|
|
103
|
+
|
|
104
|
+
# Progressive simplification when over budget
|
|
105
|
+
skip_intra = 0
|
|
106
|
+
if (est > max_arch * 1.3) skip_intra = 1
|
|
107
|
+
reduce_ext = 0
|
|
108
|
+
if (est > max_arch * 1.6) { reduce_ext = 1; n_show_ext = (n_show_ext > 5) ? 5 : n_show_ext; for (i = 1; i <= n_show_ext; i++) show_ext[extn[i]] = 1 }
|
|
109
|
+
|
|
110
|
+
# Count group sizes
|
|
111
|
+
for (i = 1; i <= ni; i++) {
|
|
112
|
+
g = igrp[intn[i]]
|
|
113
|
+
if (g != "") grp_size[g]++
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
print "graph TD"
|
|
117
|
+
|
|
118
|
+
# Root-level nodes (no group or group with single member)
|
|
119
|
+
for (i = 1; i <= ni; i++) {
|
|
120
|
+
n = intn[i]
|
|
121
|
+
g = igrp[n]
|
|
122
|
+
if (g == "" || grp_size[g] <= 1) {
|
|
123
|
+
printf " %s[\"%s\"]\n", safe_id(n), clean_label(n)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Grouped subgraphs
|
|
128
|
+
for (gi = 1; gi <= ng; gi++) {
|
|
129
|
+
g = grp_order[gi]
|
|
130
|
+
if (grp_size[g] <= 1) continue
|
|
131
|
+
printf " subgraph g_%s[\"%s\"]\n", safe_id(g), g
|
|
132
|
+
for (i = 1; i <= ni; i++) {
|
|
133
|
+
n = intn[i]
|
|
134
|
+
if (igrp[n] == g) {
|
|
135
|
+
printf " %s[\"%s\"]\n", safe_id(n), clean_label(n)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
print " end"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# External subgraph
|
|
142
|
+
if (n_show_ext > 0) {
|
|
143
|
+
print " subgraph g_ext[\"external\"]"
|
|
144
|
+
for (i = 1; i <= n_show_ext; i++) {
|
|
145
|
+
n = extn[i]
|
|
146
|
+
printf " ext_%s[\"%s\"]\n", safe_id(n), n
|
|
147
|
+
}
|
|
148
|
+
print " end"
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# Edges
|
|
152
|
+
edge_count = 0
|
|
153
|
+
for (i = 1; i <= ne; i++) {
|
|
154
|
+
s = esrc[i]; d = edst[i]
|
|
155
|
+
|
|
156
|
+
if (s ~ /^ext:/) { n = substr(s, 5); if (!(n in show_ext)) continue }
|
|
157
|
+
if (d ~ /^ext:/) { n = substr(d, 5); if (!(n in show_ext)) continue }
|
|
158
|
+
|
|
159
|
+
# Skip same-group internal edges if over budget
|
|
160
|
+
if (skip_intra && !(s ~ /^ext:/) && !(d ~ /^ext:/) && igrp[s] != "" && igrp[s] == igrp[d]) continue
|
|
161
|
+
|
|
162
|
+
sid = (s ~ /^ext:/) ? "ext_" safe_id(substr(s, 5)) : safe_id(s)
|
|
163
|
+
did = (d ~ /^ext:/) ? "ext_" safe_id(substr(d, 5)) : safe_id(d)
|
|
164
|
+
|
|
165
|
+
printf " %s --> %s\n", sid, did
|
|
166
|
+
edge_count++
|
|
167
|
+
|
|
168
|
+
if (edge_count >= max_arch) break
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# Summary comment
|
|
172
|
+
hidden = (nx > n_show_ext) ? nx - n_show_ext : 0
|
|
173
|
+
printf " %% %d modules", ni
|
|
174
|
+
if (n_show_ext > 0) printf ", %d deps", n_show_ext
|
|
175
|
+
if (hidden > 0) printf " (%d hidden)", hidden
|
|
176
|
+
printf ", %d edges\n", edge_count
|
|
177
|
+
}
|
|
178
|
+
'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# crew.sh — PipeMD Crew coordination block.
|
|
4
|
+
#
|
|
5
|
+
# Thin delegator: the heavy logic (session ledger, process scan, conflict
|
|
6
|
+
# detection) lives in the `pmd` binary so it stays unit-testable. This script
|
|
7
|
+
# only applies the token budget and calls `pmd crew render`.
|
|
8
|
+
|
|
9
|
+
source "$(dirname "$0")/../lib/limit.sh" 2>/dev/null || MAX_CREW="${PMD_MAX_CREW:-40}"
|
|
10
|
+
|
|
11
|
+
if command -v pmd >/dev/null 2>&1; then
|
|
12
|
+
PMD_MAX_CREW="${MAX_CREW:-40}" pmd crew render 2>/dev/null || echo "_(crew block unavailable)_"
|
|
13
|
+
else
|
|
14
|
+
echo "_(pmd not on PATH — crew coordination block unavailable)_"
|
|
15
|
+
fi
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Django model metadata — model names and field summaries
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
files=$(find . -name 'models.py' -not -path '*/venv/*' -not -path '*/.venv/*' -not -path '*/node_modules/*' 2>/dev/null | head -5)
|
|
6
|
+
[ -z "$files" ] && echo "No Django models found" && exit 0
|
|
7
|
+
echo "$files" | while IFS= read -r f; do
|
|
8
|
+
[ -z "$f" ] && continue
|
|
9
|
+
echo "=== $f ==="
|
|
10
|
+
awk '/^class [A-Z]/{gsub(/\(.*/,"",$0); print "Model: "$2; next} /^[[:space:]]+[a-z_]+ = models\./{gsub(/ = .*/,"",$1); print " "$1; next}' "$f" | head -"$MAX_DJANGO"
|
|
11
|
+
done | head -30
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Prisma model metadata — model names, field counts, enums
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
SCHEMA=""
|
|
6
|
+
for f in prisma/schema.prisma src/prisma/schema.prisma; do
|
|
7
|
+
[ -f "$f" ] && SCHEMA="$f" && break
|
|
8
|
+
done
|
|
9
|
+
[ -z "$SCHEMA" ] && echo "No prisma schema found" && exit 0
|
|
10
|
+
|
|
11
|
+
out=""
|
|
12
|
+
in_model=0; model=""; fields=0
|
|
13
|
+
while IFS= read -r line; do
|
|
14
|
+
if [[ "$line" =~ ^model[[:space:]]+([A-Za-z_][A-Za-z0-9_]*) ]]; then
|
|
15
|
+
in_model=1; model="${BASH_REMATCH[1]}"; fields=0
|
|
16
|
+
elif [[ "$line" =~ ^enum[[:space:]]+([A-Za-z_][A-Za-z0-9_]*) ]]; then
|
|
17
|
+
in_model=0; enum_name="${BASH_REMATCH[1]}"; enum_vals=""
|
|
18
|
+
elif (( in_model )); then
|
|
19
|
+
if [[ "$line" =~ ^[[:space:]]+@@ ]]; then
|
|
20
|
+
continue
|
|
21
|
+
elif [[ "$line" =~ ^[[:space:]]+[a-zA-Z] ]]; then
|
|
22
|
+
(( fields++ ))
|
|
23
|
+
elif [[ "$line" =~ ^\} ]]; then
|
|
24
|
+
out+="${model} (${fields} fields)\n"
|
|
25
|
+
in_model=0
|
|
26
|
+
fi
|
|
27
|
+
fi
|
|
28
|
+
done < "$SCHEMA"
|
|
29
|
+
|
|
30
|
+
# Extract enums separately
|
|
31
|
+
awk '/^enum[[:space:]]/{e=$2;v="";next} /^[[:space:]]+[A-Z]/{v=v?v","$1:$1} /^\}/{if(e)print "enum "e" = ["v"]";e=""}' "$SCHEMA"
|
|
32
|
+
|
|
33
|
+
printf '%b' "$out" | head -"$MAX_PRISMA"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# SQLAlchemy model metadata — model signatures and tables
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
files=$(find . -name '*.py' -not -path '*/venv/*' -not -path '*/.venv/*' -not -path '*/node_modules/*' -not -path '*/__pycache__/*' 2>/dev/null | head -20)
|
|
6
|
+
[ -z "$files" ] && echo "No SQLAlchemy models detected" && exit 0
|
|
7
|
+
out=$(echo "$files" | while IFS= read -r f; do
|
|
8
|
+
[ -z "$f" ] && continue
|
|
9
|
+
grep -n 'class.*Model\|__tablename__\|Column(' "$f" 2>/dev/null | head -5
|
|
10
|
+
done)
|
|
11
|
+
[ -z "$out" ] && echo "No SQLAlchemy models detected" && exit 0
|
|
12
|
+
echo "$out" | head -"$MAX_SQLALCHEMY"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Angular route metadata — route definitions from routing modules
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
files=$(find src -name '*-routing.module.ts' -o -name '*-routing.module.js' 2>/dev/null | grep -v '/node_modules/')
|
|
6
|
+
[ -z "$files" ] && echo "No Angular routing modules found" && exit 0
|
|
7
|
+
echo "$files" | while IFS= read -r f; do
|
|
8
|
+
[ -z "$f" ] && continue
|
|
9
|
+
echo "=== $f ==="
|
|
10
|
+
grep -E 'path:\s*['\''"]' "$f" 2>/dev/null | sed -E "s/.*path:\s*['\"]([^'\"]+)['\"].*/\1/" | head -10
|
|
11
|
+
done | head -"$MAX_ANGULAR"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Next.js App Router route tree — page.tsx files
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
if [ ! -d app ]; then
|
|
6
|
+
echo "No Next.js app/ directory found"
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
out=$(find app -name 'page.tsx' -o -name 'page.ts' -o -name 'page.jsx' -o -name 'page.js' 2>/dev/null \
|
|
10
|
+
| sed 's|^app||;s|/page\.\(tsx\|ts\|jsx\|js\)$||;s|^$|/|' \
|
|
11
|
+
| sort)
|
|
12
|
+
[ -z "$out" ] && echo "No Next.js pages found" && exit 0
|
|
13
|
+
echo "$out" | head -"$MAX_NEXTJS"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# React component metadata — exported function components and Props types
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(grep -rn --include='*.tsx' --include='*.jsx' \
|
|
6
|
+
-E '^export (default )?function [A-Z][A-Za-z]*|^export const [A-Z][A-Za-z]* =|^const [A-Z][A-Za-z]*: React\.FC' \
|
|
7
|
+
. 2>/dev/null | grep -v 'node_modules' \
|
|
8
|
+
| sed -E 's/:[0-9]+:.*export (default )?(function |const )([A-Z][A-Za-z]*).*/\3/' \
|
|
9
|
+
| sort -u | head -"$MAX_REACT")
|
|
10
|
+
[ -z "$out" ] && echo "No React components detected" && exit 0
|
|
11
|
+
echo "$out"
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Git diff stat — truncated with count if large
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(git diff --stat 2>/dev/null)
|
|
6
|
+
limit_output "$out" "$MAX_DIFF" "$(echo "$out" | head -10 && echo "... $(($(echo "$out" | wc -l) - 10)) more files")"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Current branch and tracking info
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
branch=$(git branch --show-current 2>/dev/null)
|
|
6
|
+
tracking=$(git rev-list --left-right --count HEAD...@'{u}' 2>/dev/null | awk '{print "ahead " $1 ", behind " $2}')
|
|
7
|
+
if [ -n "$branch" ]; then
|
|
8
|
+
echo "$branch"
|
|
9
|
+
if [ -n "$tracking" ]; then
|
|
10
|
+
echo "$tracking"
|
|
11
|
+
else
|
|
12
|
+
echo "no upstream"
|
|
13
|
+
fi
|
|
14
|
+
else
|
|
15
|
+
echo "not a git repository"
|
|
16
|
+
fi
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Git log — last 10 commits
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(git log --oneline --date=short --format="%h %ad %s" -10 2>/dev/null | cut -c1-256)
|
|
6
|
+
limit_output "$out" "$MAX_LOG" "$(echo "$out" | head -3 && echo '... more commits')"
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
# Git status — summary counts if too many files
|
|
4
|
+
source "$(dirname "$0")/../lib/limit.sh"
|
|
5
|
+
out=$(git status --short --branch 2>/dev/null)
|
|
6
|
+
limit_output "$out" "$MAX_STATUS" "$(echo "$out" | head -5; echo "... and $(($(echo "$out" | wc -l) - 5)) more changes")"
|