-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·141 lines (127 loc) · 5.07 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·141 lines (127 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env sh
# install.sh — copy the outsource skill into Claude Code's skill directory.
#
# Usage:
# ./install.sh install into ~/.claude/skills/outsource/
# ./install.sh --project install into ./.claude/skills/outsource/ (cwd)
# ./install.sh --print show the plan without writing
# ./install.sh --force overwrite even if the install was hand-edited
#
# Upgrades over an unmodified install proceed without --force: each install
# writes a checksum manifest (.install-checksums), and the next run refuses
# only when files changed since the LAST INSTALL (i.e. someone hand-edited
# the installed copy). references/local-overlay.md is always preserved and
# never checksummed; when the install has none, an untracked
# local-overlay*.md at the repo root seeds it. references/overlays/ — the
# declared project overlays — is preserved the same way and for the same
# reason: it is the user's content living inside a directory this script
# deletes wholesale.
set -eu
SRC="$(cd "$(dirname "$0")" && pwd)/skills/outsource"
DEST="$HOME/.claude/skills/outsource"
MANIFEST=".install-checksums"
PRINT=0
FORCE=0
for arg in "$@"; do
case "$arg" in
--project) DEST="$(pwd)/.claude/skills/outsource" ;;
--print) PRINT=1 ;;
--force) FORCE=1 ;;
-h|--help) sed -n '2,15p' "$0"; exit 0 ;;
*) echo "unknown option: $arg" >&2; exit 2 ;;
esac
done
checksum() {
if command -v sha256sum >/dev/null 2>&1; then sha256sum "$@"; else shasum -a 256 "$@"; fi
}
echo "install: $SRC -> $DEST"
[ "$PRINT" -eq 1 ] && exit 0
# Tamper check: refuse to clobber local edits unless --force.
if [ -d "$DEST" ] && [ "$FORCE" -ne 1 ]; then
if [ -f "$DEST/$MANIFEST" ]; then
if ! (cd "$DEST" && checksum -c "$MANIFEST" >/dev/null 2>&1); then
echo "refusing: $DEST was modified since the last install." >&2
echo "use --force to discard those local edits (local-overlay.md survives either way)." >&2
exit 1
fi
elif ! diff -rq -x local-overlay.md -x overlays -x "$MANIFEST" "$SRC" "$DEST" >/dev/null 2>&1; then
echo "refusing: $DEST differs and has no install manifest (pre-manifest install)." >&2
echo "use --force once; upgrades after that won't need it." >&2
exit 1
fi
fi
# Preserve a user's local overlay across upgrades (never shipped by this repo).
OVERLAY="$DEST/references/local-overlay.md"
TMP_OVERLAY=""
if [ -f "$OVERLAY" ]; then
TMP_OVERLAY="$(mktemp)"
cp "$OVERLAY" "$TMP_OVERLAY"
fi
# Same for declared project overlays. They are user content that happens to
# live under the installed tree, and the install below is a clean one.
DECLARED="$DEST/references/overlays"
TMP_DECLARED=""
if [ -d "$DECLARED" ]; then
TMP_DECLARED="$(mktemp -d)"
cp -R "$DECLARED/." "$TMP_DECLARED/"
fi
# The binary in bin/ is a build artifact, and installing a stale one is
# silently wrong: tests/reproducible-build.test.sh guards the COMMITTED
# artifact, not this action. Measured 2026-08-26 — a source fix followed by
# ./install.sh printed "installed." while shipping the previous binary, and
# the change looked like it had not worked.
BIN="$SRC/bin/outsource"
if [ -e "$BIN" ]; then
ROOT="$(cd "$(dirname "$0")" && pwd)"
STALE=""
for d in "$ROOT/cmd" "$ROOT/internal"; do
[ -d "$d" ] || continue
found="$(find "$d" -name '*.go' -newer "$BIN" -print 2>/dev/null | head -1)"
if [ -n "$found" ]; then STALE="$found"; break; fi
done
if [ -n "$STALE" ]; then
echo "install: $STALE is newer than bin/outsource — run ./build.sh first." >&2
echo "install: refusing, because copying now would install the previous binary." >&2
exit 1
fi
fi
# Clean install so files removed upstream don't linger.
rm -rf "$DEST"
mkdir -p "$DEST"
cp -R "$SRC/." "$DEST/"
if [ -n "$TMP_OVERLAY" ]; then
mkdir -p "$DEST/references"
cp "$TMP_OVERLAY" "$OVERLAY"
rm -f "$TMP_OVERLAY"
echo "preserved local overlay: $OVERLAY"
fi
if [ -n "$TMP_DECLARED" ]; then
mkdir -p "$DECLARED"
cp -R "$TMP_DECLARED/." "$DECLARED/"
rm -rf "$TMP_DECLARED"
echo "preserved declared overlays: $DECLARED"
fi
# Seed the overlay from a personal source kept untracked at the repo root
# (`local-overlay*.md`). The repo never ships references/local-overlay.md,
# but a source file sitting here declares itself as exactly that — without
# this step it silently never reaches the install. A preserved overlay from
# the previous install wins over the seed.
if [ ! -f "$OVERLAY" ]; then
for seed in "$(cd "$(dirname "$0")" && pwd)"/local-overlay*.md; do
[ -f "$seed" ] || continue
mkdir -p "$DEST/references"
cp "$seed" "$OVERLAY"
echo "seeded local overlay from: $seed"
break
done
fi
# Record what this install shipped, so the next run can tell "upgrade over
# a clean install" (fine) from "someone hand-edited the copy" (refuse).
(
cd "$DEST" &&
find . -type f ! -name "$MANIFEST" ! -path "./references/local-overlay.md" \
! -path "./references/overlays/*" \
| LC_ALL=C sort \
| while IFS= read -r f; do checksum "$f"; done
) > "$DEST/$MANIFEST"
echo "installed. In Claude Code, invoke with /outsource (backends: grok CLI, and/or a z.ai key for the GLM harnesses)."