Repository navigation
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·149 lines (128 loc) · 4.87 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·149 lines (128 loc) · 4.87 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
#!/usr/bin/env bash
set -euo pipefail
TAG_FLAG=""
while [[ $# -gt 0 ]]; do
case $1 in
--tag) TAG_FLAG="$2"; shift 2 ;;
*) break ;;
esac
done
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
info() { printf "${GREEN}[mesa]${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}[mesa]${NC} %s\n" "$1"; }
error() { printf "${RED}[mesa]${NC} %s\n" "$1" >&2; exit 1; }
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
detect_local_repo() {
if [ -f "$SCRIPT_DIR/package.json" ] && grep -q '"opencode-mesa"' "$SCRIPT_DIR/package.json" 2>/dev/null; then
echo "$SCRIPT_DIR"
return 0
fi
return 1
}
LOCAL_REPO="$(detect_local_repo)" || true
if [ -n "$LOCAL_REPO" ]; then
INSTALL_DIR="$LOCAL_REPO"
info "Detected local repo at $INSTALL_DIR (skipping clone)"
else
REPO_URL="${1:-https://github.com/hacklabr/opencode-mesa}"
INSTALL_DIR="${2:-$HOME/.local/share/opencode-mesa}"
command -v git >/dev/null 2>&1 || error "git is required"
if [ -d "$INSTALL_DIR" ]; then
info "Updating existing installation at $INSTALL_DIR"
git -C "$INSTALL_DIR" fetch --unshallow 2>/dev/null || true
git -C "$INSTALL_DIR" fetch origin --tags
if [ -n "$TAG_FLAG" ]; then
git -C "$INSTALL_DIR" checkout "tags/$TAG_FLAG"
else
git -C "$INSTALL_DIR" reset --hard origin/main
fi
git -C "$INSTALL_DIR" submodule update --init --recursive
else
info "Cloning Mesa into $INSTALL_DIR"
git clone --depth 1 "$REPO_URL" "$INSTALL_DIR"
git -C "$INSTALL_DIR" submodule update --init --recursive
fi
fi
command -v node >/dev/null 2>&1 || error "node is required"
command -v npm >/dev/null 2>&1 || error "npm is required"
# Mesa requires node:sqlite (Node >= 22.5.0) for the runtime-agnostic SQLite driver.
NODE_VERSION="$(node -e "process.stdout.write(process.versions.node)" 2>/dev/null || echo 0)"
NODE_MAJOR_MINOR="$(printf '%s.%s' $(echo "$NODE_VERSION" | cut -d. -f1) $(echo "$NODE_VERSION" | cut -d. -f2))"
# Compare via sort -V; bail if older than 22.5
if [ "$(printf '%s\n22.5' "$NODE_MAJOR_MINOR" | sort -V | head -n1)" != "22.5" ]; then
error "Node >= 22.5.0 is required (have $NODE_VERSION). node:sqlite is needed by the Mesa SQLite driver."
fi
info "Installing dependencies"
rm -rf "$INSTALL_DIR/node_modules"
npm ci --prefix "$INSTALL_DIR" 2>/dev/null || npm install --prefix "$INSTALL_DIR"
info "Building plugin"
npm run build --prefix "$INSTALL_DIR"
info "Generating agents"
GLOBAL_AGENTS_DIR="$HOME/.config/opencode/agents"
node "$INSTALL_DIR/src/setup/generate-agents.js" "$GLOBAL_AGENTS_DIR"
PLUGIN_PATH="file://$INSTALL_DIR/dist/index.js"
CONFIG_DIR="$HOME/.config/opencode"
CONFIG_FILE="$CONFIG_DIR/opencode.json"
# Deployment strategy:
# - OpenCode V2 ignores local file:// entries in the `plugins` config key,
# so V2 uses a discovery stub in ~/.config/opencode/plugins/ (same
# mechanism as other local plugins).
# - OpenCode V1 uses the legacy `plugin` config key.
# - Unknown version: deploy both (each host ignores the other's mechanism).
OC_VERSION="$(opencode --version 2>/dev/null | head -1 || true)"
OC_MAJOR="$(printf '%s' "$OC_VERSION" | grep -oE '[0-9]+' | head -1 || true)"
OC_V2=false
if [ -n "$OC_MAJOR" ] && [ "$OC_MAJOR" -ge 2 ]; then
OC_V2=true
fi
info ""
info "Configuring plugin globally..."
mkdir -p "$CONFIG_DIR"
# V2 discovery stub (always written — inert on V1)
PLUGINS_DIR="$CONFIG_DIR/plugins"
STUB_FILE="$PLUGINS_DIR/mesa.js"
mkdir -p "$PLUGINS_DIR"
cat > "$STUB_FILE" <<EOstub
// Managed by the opencode-mesa installer — OpenCode V2 discovery entry.
export { default } from "$PLUGIN_PATH"
EOstub
info "V2 discovery stub: $STUB_FILE"
if $OC_V2; then
info "Detected OpenCode V2 (${OC_VERSION:-unknown})"
# Remove legacy config-key entries so V1 hosts cannot double-load.
if [ -f "$CONFIG_FILE" ] && grep -q "opencode-mesa" "$CONFIG_FILE" 2>/dev/null; then
node "$INSTALL_DIR/src/setup/remove-plugin.cjs" "$CONFIG_FILE" || true
fi
else
if [ -n "$OC_MAJOR" ]; then
info "Detected OpenCode V1 (${OC_VERSION})"
else
info "OpenCode version not detected — also writing the legacy V1 config key"
fi
if [ -f "$CONFIG_FILE" ]; then
node "$INSTALL_DIR/src/setup/add-plugin.cjs" "$CONFIG_FILE" "$PLUGIN_PATH" plugin
info "Plugin added to $CONFIG_FILE (plugin key)"
else
cat > "$CONFIG_FILE" <<EOCFG
{
"\$schema": "https://opencode.ai/config.json",
"plugin": ["$PLUGIN_PATH"]
}
EOCFG
info "Created $CONFIG_FILE with plugin configured"
fi
fi
info ""
info "Done. Restart opencode to load the plugin."
info ""
info "Install dir: $INSTALL_DIR"
info "Agents generated in $GLOBAL_AGENTS_DIR"
info "To also generate agents in a specific project, run:"
info " node $INSTALL_DIR/src/setup/generate-agents.js /path/to/project/.opencode/agents"
info ""
info "Switch agents with Tab or /agent:"
info " /agent briefing-writer — start a discovery session"
info " /agent manager — orchestrate a specialist team"