-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathinstall-opencode.sh
More file actions
executable file
·154 lines (128 loc) · 4.35 KB
/
Copy pathinstall-opencode.sh
File metadata and controls
executable file
·154 lines (128 loc) · 4.35 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
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env sh
set -eu
repo=$(CDPATH= cd -- "$(dirname -- "$0")" 2>/dev/null && pwd || pwd)
source_opencode="$repo/.opencode"
cleanup_dir=""
config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/opencode"
skills_dir="$config_dir/skills"
commands_dir="$config_dir/commands"
config_file="$config_dir/opencode.json"
agents_file="$config_dir/AGENTS.caveman.md"
skills="caveman caveman-commit caveman-review caveman-help caveman-compress"
default_level="${CAVEMAN_OPENCODE_DEFAULT_LEVEL:-full}"
case "$default_level" in
lite|full|ultra|wenyan|wenyan-lite|wenyan-ultra) ;;
*)
echo "ERROR: CAVEMAN_OPENCODE_DEFAULT_LEVEL must be one of: lite, full, ultra, wenyan, wenyan-lite, wenyan-ultra" >&2
exit 1
;;
esac
cleanup() {
if [ -n "$cleanup_dir" ] && [ -d "$cleanup_dir" ]; then
rm -rf "$cleanup_dir"
fi
}
trap cleanup EXIT
if [ ! -f "$source_opencode/AGENTS.md" ]; then
archive_url="${CAVEMAN_OPENCODE_ARCHIVE_URL:-https://github.com/anthonystepvoy/caveman-opencode/archive/refs/heads/main.tar.gz}"
cleanup_dir="${TMPDIR:-/tmp}/caveman-opencode-$$"
archive_file="$cleanup_dir/source.tar.gz"
mkdir -p "$cleanup_dir"
echo "Downloading Caveman for OpenCode from $archive_url"
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$archive_url" -o "$archive_file"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$archive_file" "$archive_url"
else
echo "ERROR: curl or wget is required for remote install" >&2
exit 1
fi
tar -xzf "$archive_file" -C "$cleanup_dir"
source_dir=$(find "$cleanup_dir" -mindepth 1 -maxdepth 1 -type d | head -n 1)
if [ -z "$source_dir" ]; then
echo "ERROR: downloaded archive did not contain a source directory" >&2
exit 1
fi
source_opencode="$source_dir/.opencode"
if [ ! -f "$source_opencode/AGENTS.md" ]; then
echo "ERROR: downloaded archive did not contain .opencode/AGENTS.md" >&2
exit 1
fi
fi
mkdir -p "$skills_dir" "$commands_dir"
for skill in $skills; do
rm -rf "$skills_dir/$skill"
cp -R "$source_opencode/skills/$skill" "$skills_dir/$skill"
done
cp "$source_opencode"/commands/*.md "$commands_dir/"
sed "s/^Default mode: full\./Default mode: $default_level./" "$source_opencode/AGENTS.md" > "$agents_file"
node - "$config_file" "$agents_file" <<'NODE'
const fs = require("fs")
const [configFile, agentsFile] = process.argv.slice(2)
const skills = ["caveman", "caveman-commit", "caveman-review", "caveman-help", "caveman-compress"]
let config = {}
function stripTrailingCommas(content) {
let result = ""
let inString = false
let escaped = false
for (let index = 0; index < content.length; index += 1) {
const character = content[index]
if (inString) {
result += character
if (escaped) {
escaped = false
} else if (character === "\\") {
escaped = true
} else if (character === '"') {
inString = false
}
continue
}
if (character === '"') {
inString = true
result += character
continue
}
if (character === ",") {
let next = index + 1
while (next < content.length && /\s/.test(content[next])) {
next += 1
}
if (content[next] === "}" || content[next] === "]") {
continue
}
}
result += character
}
return result
}
function parseConfig(content) {
try {
return JSON.parse(content)
} catch (error) {
const normalized = stripTrailingCommas(content)
if (normalized === content) {
throw error
}
return JSON.parse(normalized)
}
}
if (fs.existsSync(configFile)) {
const content = fs.readFileSync(configFile, "utf8")
config = parseConfig(content)
}
config.instructions = Array.isArray(config.instructions) ? config.instructions : []
if (!config.instructions.includes(agentsFile)) {
config.instructions.push(agentsFile)
}
config.permission = config.permission && typeof config.permission === "object" ? config.permission : {}
config.permission.skill =
config.permission.skill && typeof config.permission.skill === "object" ? config.permission.skill : {}
for (const skill of skills) {
config.permission.skill[skill] = "allow"
}
fs.writeFileSync(configFile, JSON.stringify(config, null, 2) + "\n")
NODE
echo "Installed Caveman for OpenCode to $config_dir"
echo "Default Caveman intensity: $default_level"
echo "Restart OpenCode, then use /caveman, /caveman-help, /caveman-review, /caveman-commit, or /caveman-compress."