Repository navigation
Expand file tree
/
Copy pathsetup
More file actions
executable file
·123 lines (114 loc) · 3.92 KB
/
Copy pathsetup
File metadata and controls
executable file
·123 lines (114 loc) · 3.92 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
#!/usr/bin/env bash
# pmstack setup: installs the pmstack skills and the pmstack command-line tool.
#
# Usage:
# ./setup /path/to/project install into that project
# ./setup install into the current folder
# ./setup --global install once for every project, in your home folder
# ./setup --dry-run show what would be copied, copy nothing
# ./setup -h show this help
#
# Project install: skills go to <project>/.claude/skills/, the tool to <project>/.pmstack/
# Global install: skills go to ~/.claude/skills/, the tool to ~/.pmstack/
#
# Running setup again replaces pmstack's own files and leaves everything else alone.
# It never touches CLAUDE.md. The tool needs Node 20 or newer and nothing else.
set -euo pipefail
SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TARGET="$(pwd)"
DRY_RUN=0
GLOBAL=0
for arg in "$@"; do
case "$arg" in
--global) GLOBAL=1 ;;
--dry-run) DRY_RUN=1 ;;
-h|--help)
# Print the leading comment block so the help never drifts from it.
awk 'NR==1{next} /^#/{sub(/^# ?/,""); print; next} {exit}' "$0"
exit 0
;;
*)
if [[ -d "$arg" ]]; then
TARGET="$(cd "$arg" && pwd)"
else
echo "Not a flag or an existing folder: $arg (run ./setup -h for help)" >&2
exit 1
fi
;;
esac
done
if [[ "$GLOBAL" == "1" ]]; then
SKILLS_DIR="$HOME/.claude/skills"
RUNTIME_DIR="$HOME/.pmstack"
echo "Installing pmstack for every project (your home folder)"
else
# Installing into the pmstack folder itself would only add clutter to the clone.
if [[ "$TARGET" == "$SRC" ]]; then
echo "This is the pmstack folder itself. Pass a project folder (./setup /path/to/project) or --global." >&2
exit 1
fi
SKILLS_DIR="$TARGET/.claude/skills"
RUNTIME_DIR="$TARGET/.pmstack"
echo "Installing pmstack into $TARGET"
fi
if [[ "$DRY_RUN" == "1" ]]; then echo "(dry run: nothing will be copied)"; fi
run() {
echo " $*"
if [[ "$DRY_RUN" == "0" ]]; then "$@"; fi
}
# Skills: every skills/<name>/ folder, copied whole. skills/README.md stays behind.
skill_dirs=()
for d in "$SRC"/skills/*/; do
if [[ -f "$d/SKILL.md" ]]; then skill_dirs+=("$d"); fi
done
if [[ "${#skill_dirs[@]}" == "0" ]]; then
echo "No skills found in $SRC/skills/. Is this a complete copy of pmstack?" >&2
exit 1
fi
for d in "${skill_dirs[@]}"; do
name="$(basename "$d")"
run mkdir -p "$SKILLS_DIR/$name"
run cp -R "$d." "$SKILLS_DIR/$name/"
done
# Runtime: the tool and the studio it serves, keeping the bin/ and docs/ layout
# because bin/pmstack.mjs imports ../docs/studio/lib/. A missing piece is
# reported at the end instead of stopping the install.
MISSING=""
copy_runtime() {
local rel="$1"
if [[ -d "$SRC/$rel" ]]; then
run mkdir -p "$RUNTIME_DIR/$rel"
run cp -R "$SRC/$rel/." "$RUNTIME_DIR/$rel/"
elif [[ -f "$SRC/$rel" ]]; then
run mkdir -p "$RUNTIME_DIR/$(dirname "$rel")"
run cp "$SRC/$rel" "$RUNTIME_DIR/$rel"
else
MISSING+=" $rel"$'\n'
fi
}
copy_runtime bin/pmstack.mjs
copy_runtime docs/studio
copy_runtime docs/assets/visuals
copy_runtime templates/tool-calls
echo ""
if [[ -n "$MISSING" ]]; then
echo "Not found in $SRC, so not copied:"
printf '%s' "$MISSING"
echo "The skills still work without these: they send you to https://ryanalberts.github.io/pmstack/studio/ instead."
echo "To add them later, update your pmstack copy and run setup again."
echo ""
fi
if [[ "$DRY_RUN" == "1" ]]; then
echo "Dry run finished. Run again without --dry-run to install."
exit 0
fi
echo "pmstack is installed."
echo " Skills: $SKILLS_DIR/pmstack-*"
if [[ -f "$RUNTIME_DIR/bin/pmstack.mjs" ]]; then echo " Tool: $RUNTIME_DIR/bin/pmstack.mjs"; fi
echo ""
echo "Next:"
echo " In Claude Code, run /pmstack-start"
if [[ -f "$RUNTIME_DIR/bin/pmstack.mjs" ]]; then
echo " Or open Eval Studio on a folder of traces:"
echo " node \"$RUNTIME_DIR/bin/pmstack.mjs\" studio /path/to/folder --open"
fi