aidevops 2.172.17 → 2.172.19
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/VERSION +1 -1
- package/aidevops.sh +1 -1
- package/package.json +2 -1
- package/scripts/npm-postinstall.cjs +13 -2
- package/setup-modules/agent-deploy.sh +627 -0
- package/setup-modules/config.sh +183 -0
- package/setup-modules/core.sh +572 -0
- package/setup-modules/mcp-setup.sh +766 -0
- package/setup-modules/migrations.sh +961 -0
- package/setup-modules/plugins.sh +588 -0
- package/setup-modules/shell-env.sh +892 -0
- package/setup-modules/tool-install.sh +1373 -0
- package/setup.sh +1 -1
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Core setup functions: requirements, permissions, location
|
|
3
|
+
# Part of aidevops setup.sh modularization (t316.3)
|
|
4
|
+
|
|
5
|
+
# Shell safety baseline
|
|
6
|
+
set -Eeuo pipefail
|
|
7
|
+
IFS=$'\n\t'
|
|
8
|
+
# shellcheck disable=SC2154 # rc is assigned by $? in the trap string
|
|
9
|
+
trap 'rc=$?; echo "[ERROR] ${BASH_SOURCE[0]}:${LINENO} exit $rc" >&2' ERR
|
|
10
|
+
shopt -s inherit_errexit 2>/dev/null || true
|
|
11
|
+
|
|
12
|
+
bootstrap_repo() {
|
|
13
|
+
# Detect if running from curl (no script directory context)
|
|
14
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
15
|
+
|
|
16
|
+
# If script_path is empty, stdin, bash, or /dev/fd/* (process substitution), we're running from curl
|
|
17
|
+
# bash <(curl ...) produces paths like /dev/fd/63
|
|
18
|
+
if [[ -z "$script_path" || "$script_path" == "/dev/stdin" || "$script_path" == "bash" || "$script_path" == /dev/fd/* ]]; then
|
|
19
|
+
print_info "Remote install detected - bootstrapping repository..."
|
|
20
|
+
|
|
21
|
+
# On macOS, offer choice: install locally or in an OrbStack VM
|
|
22
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
23
|
+
echo ""
|
|
24
|
+
echo "Where would you like to install aidevops?"
|
|
25
|
+
echo ""
|
|
26
|
+
echo " 1) Install on this Mac (recommended)"
|
|
27
|
+
echo " 2) Install in a Linux VM (via OrbStack)"
|
|
28
|
+
echo ""
|
|
29
|
+
read -r -p "Choose [1/2] (default: 1): " install_target
|
|
30
|
+
|
|
31
|
+
if [[ "$install_target" == "2" ]]; then
|
|
32
|
+
print_info "Setting up OrbStack VM installation..."
|
|
33
|
+
|
|
34
|
+
# Install OrbStack if not present
|
|
35
|
+
if ! command -v orb >/dev/null 2>&1 && [[ ! -d "/Applications/OrbStack.app" ]]; then
|
|
36
|
+
if command -v brew >/dev/null 2>&1; then
|
|
37
|
+
print_info "Installing OrbStack via Homebrew..."
|
|
38
|
+
brew install --cask orbstack
|
|
39
|
+
else
|
|
40
|
+
print_error "Homebrew is required to install OrbStack"
|
|
41
|
+
echo "Install Homebrew first: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
|
42
|
+
echo "Then re-run this installer."
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Wait for OrbStack to be ready
|
|
48
|
+
if ! command -v orb >/dev/null 2>&1; then
|
|
49
|
+
print_info "Waiting for OrbStack CLI to become available..."
|
|
50
|
+
# OrbStack installs the CLI at /usr/local/bin/orb
|
|
51
|
+
local wait_count=0
|
|
52
|
+
while ! command -v orb >/dev/null 2>&1 && [[ $wait_count -lt 30 ]]; do
|
|
53
|
+
sleep 2
|
|
54
|
+
((++wait_count))
|
|
55
|
+
done
|
|
56
|
+
if ! command -v orb >/dev/null 2>&1; then
|
|
57
|
+
print_error "OrbStack CLI not found after installation"
|
|
58
|
+
echo "Open OrbStack.app manually, then re-run this installer."
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Create or use existing Ubuntu VM
|
|
64
|
+
local vm_name="aidevops"
|
|
65
|
+
if orb list 2>/dev/null | grep -qxF "$vm_name"; then
|
|
66
|
+
print_info "Using existing OrbStack VM: $vm_name"
|
|
67
|
+
else
|
|
68
|
+
print_info "Creating Ubuntu VM: $vm_name..."
|
|
69
|
+
orb create ubuntu "$vm_name"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Run the installer inside the VM
|
|
73
|
+
print_info "Installing aidevops inside the VM..."
|
|
74
|
+
echo ""
|
|
75
|
+
orb run -m "$vm_name" bash -c 'bash <(curl -fsSL https://aidevops.sh/install)'
|
|
76
|
+
|
|
77
|
+
echo ""
|
|
78
|
+
print_success "aidevops installed in OrbStack VM: $vm_name"
|
|
79
|
+
echo ""
|
|
80
|
+
echo "To use aidevops in the VM:"
|
|
81
|
+
echo " orb shell $vm_name # Enter the VM"
|
|
82
|
+
echo " orb run -m $vm_name opencode # Run OpenCode directly"
|
|
83
|
+
echo ""
|
|
84
|
+
exit 0
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Auto-install git if missing (required for cloning)
|
|
89
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
90
|
+
print_warning "git is required but not installed - attempting auto-install..."
|
|
91
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
92
|
+
# macOS: xcode-select --install triggers git install
|
|
93
|
+
print_info "Installing Xcode Command Line Tools (includes git)..."
|
|
94
|
+
if xcode-select --install 2>/dev/null; then
|
|
95
|
+
# Wait for installation to complete (timeout after 5 minutes)
|
|
96
|
+
print_info "Waiting for Xcode CLT installation to complete (timeout: 5m)..."
|
|
97
|
+
local xcode_wait=0
|
|
98
|
+
local xcode_max_wait=300
|
|
99
|
+
until command -v git >/dev/null 2>&1; do
|
|
100
|
+
sleep 5
|
|
101
|
+
xcode_wait=$((xcode_wait + 5))
|
|
102
|
+
if [[ $xcode_wait -ge $xcode_max_wait ]]; then
|
|
103
|
+
print_error "Timed out waiting for Xcode CLT installation after ${xcode_max_wait}s"
|
|
104
|
+
echo "Complete the installation manually, then re-run this installer."
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
done
|
|
108
|
+
print_success "git installed via Xcode Command Line Tools"
|
|
109
|
+
else
|
|
110
|
+
# Already installed or failed
|
|
111
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
112
|
+
print_error "git installation failed"
|
|
113
|
+
echo "Install git manually: brew install git (macOS)"
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
fi
|
|
117
|
+
elif command -v apt-get >/dev/null 2>&1; then
|
|
118
|
+
print_info "Installing git via apt..."
|
|
119
|
+
sudo apt-get update -qq && sudo apt-get install -y -qq git
|
|
120
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
121
|
+
print_error "git installation failed"
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
|
124
|
+
print_success "git installed"
|
|
125
|
+
elif command -v dnf >/dev/null 2>&1; then
|
|
126
|
+
print_info "Installing git via dnf..."
|
|
127
|
+
sudo dnf install -y git
|
|
128
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
129
|
+
print_error "git installation failed"
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
print_success "git installed"
|
|
133
|
+
elif command -v yum >/dev/null 2>&1; then
|
|
134
|
+
print_info "Installing git via yum..."
|
|
135
|
+
sudo yum install -y git
|
|
136
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
137
|
+
print_error "git installation failed"
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
print_success "git installed"
|
|
141
|
+
elif command -v pacman >/dev/null 2>&1; then
|
|
142
|
+
print_info "Installing git via pacman..."
|
|
143
|
+
sudo pacman -S --noconfirm git
|
|
144
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
145
|
+
print_error "git installation failed"
|
|
146
|
+
exit 1
|
|
147
|
+
fi
|
|
148
|
+
print_success "git installed"
|
|
149
|
+
elif command -v apk >/dev/null 2>&1; then
|
|
150
|
+
print_info "Installing git via apk..."
|
|
151
|
+
sudo apk add git
|
|
152
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
153
|
+
print_error "git installation failed"
|
|
154
|
+
exit 1
|
|
155
|
+
fi
|
|
156
|
+
print_success "git installed"
|
|
157
|
+
else
|
|
158
|
+
print_error "git is required but not installed and no supported package manager found"
|
|
159
|
+
echo "Install git manually and re-run the installer"
|
|
160
|
+
exit 1
|
|
161
|
+
fi
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Create parent directory
|
|
165
|
+
mkdir -p "$(dirname "$INSTALL_DIR")"
|
|
166
|
+
|
|
167
|
+
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
|
168
|
+
print_info "Existing installation found - updating..."
|
|
169
|
+
cd "$INSTALL_DIR" || exit 1
|
|
170
|
+
if ! git pull --ff-only; then
|
|
171
|
+
print_warning "Git pull failed - trying reset to origin/main"
|
|
172
|
+
git fetch origin
|
|
173
|
+
git reset --hard origin/main
|
|
174
|
+
fi
|
|
175
|
+
else
|
|
176
|
+
print_info "Cloning aidevops to $INSTALL_DIR..."
|
|
177
|
+
if [[ -d "$INSTALL_DIR" ]]; then
|
|
178
|
+
print_warning "Directory exists but is not a git repo - backing up"
|
|
179
|
+
mv "$INSTALL_DIR" "$INSTALL_DIR.backup.$(date +%Y%m%d_%H%M%S)"
|
|
180
|
+
fi
|
|
181
|
+
if ! git clone "$REPO_URL" "$INSTALL_DIR"; then
|
|
182
|
+
print_error "Failed to clone repository"
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
print_success "Repository ready at $INSTALL_DIR"
|
|
188
|
+
|
|
189
|
+
# Re-execute the local script
|
|
190
|
+
cd "$INSTALL_DIR" || exit 1
|
|
191
|
+
exec bash "./setup.sh" "$@"
|
|
192
|
+
fi
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Detect package manager
|
|
196
|
+
detect_package_manager() {
|
|
197
|
+
if command -v brew >/dev/null 2>&1; then
|
|
198
|
+
echo "brew"
|
|
199
|
+
elif command -v apt-get >/dev/null 2>&1; then
|
|
200
|
+
echo "apt"
|
|
201
|
+
elif command -v dnf >/dev/null 2>&1; then
|
|
202
|
+
echo "dnf"
|
|
203
|
+
elif command -v yum >/dev/null 2>&1; then
|
|
204
|
+
echo "yum"
|
|
205
|
+
elif command -v pacman >/dev/null 2>&1; then
|
|
206
|
+
echo "pacman"
|
|
207
|
+
elif command -v apk >/dev/null 2>&1; then
|
|
208
|
+
echo "apk"
|
|
209
|
+
else
|
|
210
|
+
echo "unknown"
|
|
211
|
+
fi
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# Install packages using detected package manager
|
|
215
|
+
# For Homebrew: runs 'brew update' with a spinner first (can take 30s+),
|
|
216
|
+
# then installs packages with HOMEBREW_NO_AUTO_UPDATE to avoid a second update.
|
|
217
|
+
install_packages() {
|
|
218
|
+
local pkg_manager="$1"
|
|
219
|
+
shift
|
|
220
|
+
local packages=("$@")
|
|
221
|
+
|
|
222
|
+
case "$pkg_manager" in
|
|
223
|
+
brew)
|
|
224
|
+
# Run brew update with spinner (Homebrew auto-update is slow and silent)
|
|
225
|
+
run_with_spinner "Updating Homebrew" brew update
|
|
226
|
+
# Install with auto-update disabled (we just ran it)
|
|
227
|
+
# Note: run_with_spinner auto-exports HOMEBREW_NO_AUTO_UPDATE for brew commands
|
|
228
|
+
run_with_spinner "Installing ${packages[*]}" brew install "${packages[@]}"
|
|
229
|
+
;;
|
|
230
|
+
apt)
|
|
231
|
+
run_with_spinner "Updating package lists" sudo apt-get update -qq
|
|
232
|
+
run_with_spinner "Installing ${packages[*]}" sudo apt-get install -y -qq "${packages[@]}"
|
|
233
|
+
;;
|
|
234
|
+
dnf)
|
|
235
|
+
run_with_spinner "Installing ${packages[*]}" sudo dnf install -y "${packages[@]}"
|
|
236
|
+
;;
|
|
237
|
+
yum)
|
|
238
|
+
run_with_spinner "Installing ${packages[*]}" sudo yum install -y "${packages[@]}"
|
|
239
|
+
;;
|
|
240
|
+
pacman)
|
|
241
|
+
run_with_spinner "Installing ${packages[*]}" sudo pacman -S --noconfirm "${packages[@]}"
|
|
242
|
+
;;
|
|
243
|
+
apk)
|
|
244
|
+
run_with_spinner "Installing ${packages[*]}" sudo apk add "${packages[@]}"
|
|
245
|
+
;;
|
|
246
|
+
*)
|
|
247
|
+
return 1
|
|
248
|
+
;;
|
|
249
|
+
esac
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Offer to install Homebrew (Linuxbrew) on Linux when brew is not available
|
|
253
|
+
# Many tools in the aidevops ecosystem (Beads, Worktrunk, bv) are distributed
|
|
254
|
+
# via Homebrew taps. On macOS, brew is almost always present. On Linux, this
|
|
255
|
+
# function offers to install it so those tools can be installed automatically.
|
|
256
|
+
# Returns: 0 if brew is now available, 1 if user declined or install failed
|
|
257
|
+
ensure_homebrew() {
|
|
258
|
+
# Already available
|
|
259
|
+
if command -v brew &>/dev/null; then
|
|
260
|
+
return 0
|
|
261
|
+
fi
|
|
262
|
+
|
|
263
|
+
# Only offer on Linux (macOS users should install Homebrew themselves)
|
|
264
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
265
|
+
print_warning "Homebrew not found. Install from https://brew.sh"
|
|
266
|
+
return 1
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
# Non-interactive mode: skip
|
|
270
|
+
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
|
271
|
+
return 1
|
|
272
|
+
fi
|
|
273
|
+
|
|
274
|
+
echo ""
|
|
275
|
+
print_info "Homebrew (Linuxbrew) is not installed."
|
|
276
|
+
print_info "Several optional tools (Beads CLI, Worktrunk, bv) install via Homebrew taps."
|
|
277
|
+
echo ""
|
|
278
|
+
read -r -p "Install Homebrew for Linux? [Y/n]: " install_brew
|
|
279
|
+
|
|
280
|
+
if [[ ! "$install_brew" =~ ^[Yy]?$ ]]; then
|
|
281
|
+
print_info "Skipped Homebrew installation"
|
|
282
|
+
return 1
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
print_info "Installing Homebrew (Linuxbrew)..."
|
|
286
|
+
|
|
287
|
+
# Prerequisites for Linuxbrew
|
|
288
|
+
if command -v apt-get &>/dev/null; then
|
|
289
|
+
sudo apt-get update -qq
|
|
290
|
+
sudo apt-get install -y -qq build-essential procps curl file git
|
|
291
|
+
elif command -v dnf &>/dev/null; then
|
|
292
|
+
sudo dnf groupinstall -y 'Development Tools'
|
|
293
|
+
sudo dnf install -y procps-ng curl file git
|
|
294
|
+
elif command -v yum &>/dev/null; then
|
|
295
|
+
sudo yum groupinstall -y 'Development Tools'
|
|
296
|
+
sudo yum install -y procps-ng curl file git
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
# Install Homebrew using verified_install pattern
|
|
300
|
+
if verified_install "Homebrew" "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh"; then
|
|
301
|
+
# Add Homebrew to PATH for this session
|
|
302
|
+
local brew_prefix="/home/linuxbrew/.linuxbrew"
|
|
303
|
+
if [[ -x "$brew_prefix/bin/brew" ]]; then
|
|
304
|
+
eval "$("$brew_prefix/bin/brew" shellenv)"
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
# Persist to shell rc files
|
|
308
|
+
local brew_line="eval \"\$($brew_prefix/bin/brew shellenv)\""
|
|
309
|
+
local rc_file
|
|
310
|
+
while IFS= read -r rc_file; do
|
|
311
|
+
[[ -z "$rc_file" ]] && continue
|
|
312
|
+
if ! grep -q 'linuxbrew' "$rc_file" 2>/dev/null; then
|
|
313
|
+
{
|
|
314
|
+
echo ""
|
|
315
|
+
echo "# Homebrew (Linuxbrew) - added by aidevops setup"
|
|
316
|
+
echo "$brew_line"
|
|
317
|
+
} >>"$rc_file"
|
|
318
|
+
fi
|
|
319
|
+
done < <(get_all_shell_rcs)
|
|
320
|
+
|
|
321
|
+
if command -v brew &>/dev/null; then
|
|
322
|
+
print_success "Homebrew installed and added to PATH"
|
|
323
|
+
return 0
|
|
324
|
+
else
|
|
325
|
+
print_warning "Homebrew installed but not yet in PATH. Restart your shell or run:"
|
|
326
|
+
echo " $brew_line"
|
|
327
|
+
return 1
|
|
328
|
+
fi
|
|
329
|
+
else
|
|
330
|
+
print_warning "Homebrew installation failed"
|
|
331
|
+
return 1
|
|
332
|
+
fi
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
# Check system requirements
|
|
336
|
+
check_requirements() {
|
|
337
|
+
print_info "Checking system requirements..."
|
|
338
|
+
|
|
339
|
+
# Ensure Homebrew is in PATH (macOS Apple Silicon)
|
|
340
|
+
if [[ -x "/opt/homebrew/bin/brew" ]] && [[ ":$PATH:" != *":/opt/homebrew/bin:"* ]]; then
|
|
341
|
+
eval "$(/opt/homebrew/bin/brew shellenv)"
|
|
342
|
+
print_warning "Homebrew not in PATH - added for this session"
|
|
343
|
+
|
|
344
|
+
# Only modify rc files during interactive setup (not updates)
|
|
345
|
+
# Users may intentionally remove these lines; re-adding on every update is harmful
|
|
346
|
+
if [[ "$NON_INTERACTIVE" != "true" ]]; then
|
|
347
|
+
# shellcheck disable=SC2016 # brew_line is written to rc files; must expand at shell startup, not now
|
|
348
|
+
local brew_line='eval "$(/opt/homebrew/bin/brew shellenv)"'
|
|
349
|
+
local fixed_rc=false
|
|
350
|
+
local rc_file
|
|
351
|
+
while IFS= read -r rc_file; do
|
|
352
|
+
[[ -z "$rc_file" ]] && continue
|
|
353
|
+
if ! grep -q '/opt/homebrew/bin/brew' "$rc_file" 2>/dev/null; then
|
|
354
|
+
{
|
|
355
|
+
echo ""
|
|
356
|
+
echo "# Homebrew (added by aidevops setup)"
|
|
357
|
+
echo "$brew_line"
|
|
358
|
+
} >>"$rc_file"
|
|
359
|
+
print_success "Added Homebrew to PATH in $rc_file"
|
|
360
|
+
fixed_rc=true
|
|
361
|
+
fi
|
|
362
|
+
done < <(get_all_shell_rcs)
|
|
363
|
+
|
|
364
|
+
if [[ "$fixed_rc" == "false" ]]; then
|
|
365
|
+
echo ""
|
|
366
|
+
echo " To fix permanently, add to your shell rc file:"
|
|
367
|
+
echo " $brew_line"
|
|
368
|
+
echo ""
|
|
369
|
+
fi
|
|
370
|
+
fi
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
# Also check Intel Mac Homebrew location
|
|
374
|
+
# Skip entirely on Apple Silicon (ARM brew exists) — Intel brew shellenv prepends
|
|
375
|
+
# /usr/local/bin to PATH, causing x86 binaries to shadow ARM ones (GH#1510)
|
|
376
|
+
if [[ -x "/usr/local/bin/brew" ]] && [[ ":$PATH:" != *":/usr/local/bin:"* ]]; then
|
|
377
|
+
# On Apple Silicon with dual brew, do NOT add Intel brew to PATH — it breaks ARM brew
|
|
378
|
+
if [[ -x "/opt/homebrew/bin/brew" ]]; then
|
|
379
|
+
print_info "Intel Homebrew found but skipped (Apple Silicon uses /opt/homebrew)"
|
|
380
|
+
else
|
|
381
|
+
eval "$(/usr/local/bin/brew shellenv)"
|
|
382
|
+
print_warning "Homebrew (/usr/local/bin) not in PATH - added for this session"
|
|
383
|
+
|
|
384
|
+
# Only modify rc files during interactive setup (not updates)
|
|
385
|
+
if [[ "$NON_INTERACTIVE" != "true" ]]; then
|
|
386
|
+
# shellcheck disable=SC2016 # intel_brew_line is written to rc files; must expand at shell startup, not now
|
|
387
|
+
local intel_brew_line='eval "$(/usr/local/bin/brew shellenv)"'
|
|
388
|
+
local intel_fixed_rc=false
|
|
389
|
+
local intel_rc
|
|
390
|
+
while IFS= read -r intel_rc; do
|
|
391
|
+
[[ -z "$intel_rc" ]] && continue
|
|
392
|
+
if ! grep -q '/usr/local/bin/brew' "$intel_rc" 2>/dev/null; then
|
|
393
|
+
{
|
|
394
|
+
echo ""
|
|
395
|
+
echo "# Homebrew Intel Mac (added by aidevops setup)"
|
|
396
|
+
echo "$intel_brew_line"
|
|
397
|
+
} >>"$intel_rc"
|
|
398
|
+
print_success "Added Homebrew to PATH in $intel_rc"
|
|
399
|
+
intel_fixed_rc=true
|
|
400
|
+
fi
|
|
401
|
+
done < <(get_all_shell_rcs)
|
|
402
|
+
|
|
403
|
+
if [[ "$intel_fixed_rc" == "false" ]]; then
|
|
404
|
+
echo ""
|
|
405
|
+
echo " To fix permanently, add to your shell rc file:"
|
|
406
|
+
echo " $intel_brew_line"
|
|
407
|
+
echo ""
|
|
408
|
+
fi
|
|
409
|
+
fi
|
|
410
|
+
fi
|
|
411
|
+
fi
|
|
412
|
+
|
|
413
|
+
local missing_deps=()
|
|
414
|
+
|
|
415
|
+
# Check for required commands
|
|
416
|
+
command -v jq >/dev/null 2>&1 || missing_deps+=("jq")
|
|
417
|
+
command -v curl >/dev/null 2>&1 || missing_deps+=("curl")
|
|
418
|
+
command -v ssh >/dev/null 2>&1 || missing_deps+=("ssh")
|
|
419
|
+
|
|
420
|
+
if [[ ${#missing_deps[@]} -gt 0 ]]; then
|
|
421
|
+
print_warning "Missing required dependencies: ${missing_deps[*]}"
|
|
422
|
+
|
|
423
|
+
local pkg_manager
|
|
424
|
+
pkg_manager=$(detect_package_manager)
|
|
425
|
+
|
|
426
|
+
if [[ "$pkg_manager" == "unknown" ]]; then
|
|
427
|
+
print_error "Could not detect package manager"
|
|
428
|
+
echo ""
|
|
429
|
+
echo "Please install manually:"
|
|
430
|
+
echo " macOS: brew install ${missing_deps[*]}"
|
|
431
|
+
echo " Ubuntu/Debian: sudo apt-get install ${missing_deps[*]}"
|
|
432
|
+
echo " Fedora: sudo dnf install ${missing_deps[*]}"
|
|
433
|
+
echo " CentOS/RHEL: sudo yum install ${missing_deps[*]}"
|
|
434
|
+
echo " Arch: sudo pacman -S ${missing_deps[*]}"
|
|
435
|
+
echo " Alpine: sudo apk add ${missing_deps[*]}"
|
|
436
|
+
exit 1
|
|
437
|
+
fi
|
|
438
|
+
|
|
439
|
+
# In non-interactive mode, fail fast on missing deps
|
|
440
|
+
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
|
441
|
+
print_error "Cannot continue without required dependencies (non-interactive mode)"
|
|
442
|
+
exit 1
|
|
443
|
+
fi
|
|
444
|
+
|
|
445
|
+
echo ""
|
|
446
|
+
read -r -p "Install missing dependencies using $pkg_manager? [Y/n]: " install_deps
|
|
447
|
+
|
|
448
|
+
if [[ "$install_deps" =~ ^[Yy]?$ ]]; then
|
|
449
|
+
print_info "Installing ${missing_deps[*]}..."
|
|
450
|
+
if install_packages "$pkg_manager" "${missing_deps[@]}"; then
|
|
451
|
+
print_success "Dependencies installed successfully"
|
|
452
|
+
else
|
|
453
|
+
print_error "Failed to install dependencies"
|
|
454
|
+
exit 1
|
|
455
|
+
fi
|
|
456
|
+
else
|
|
457
|
+
print_error "Cannot continue without required dependencies"
|
|
458
|
+
exit 1
|
|
459
|
+
fi
|
|
460
|
+
fi
|
|
461
|
+
|
|
462
|
+
print_success "All required dependencies found"
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
# Check for quality/linting tools (shellcheck, shfmt)
|
|
466
|
+
# These are optional but recommended for development
|
|
467
|
+
check_quality_tools() {
|
|
468
|
+
print_info "Checking quality tools..."
|
|
469
|
+
|
|
470
|
+
local missing_tools=()
|
|
471
|
+
|
|
472
|
+
# Check for shellcheck
|
|
473
|
+
if command -v shellcheck >/dev/null 2>&1; then
|
|
474
|
+
print_success "shellcheck: $(shellcheck --version | head -1)"
|
|
475
|
+
else
|
|
476
|
+
missing_tools+=("shellcheck")
|
|
477
|
+
fi
|
|
478
|
+
|
|
479
|
+
# Check for shfmt
|
|
480
|
+
if command -v shfmt >/dev/null 2>&1; then
|
|
481
|
+
print_success "shfmt: $(shfmt --version)"
|
|
482
|
+
else
|
|
483
|
+
missing_tools+=("shfmt")
|
|
484
|
+
fi
|
|
485
|
+
|
|
486
|
+
# If all tools present, return early
|
|
487
|
+
if [[ ${#missing_tools[@]} -eq 0 ]]; then
|
|
488
|
+
print_success "All quality tools installed"
|
|
489
|
+
return 0
|
|
490
|
+
fi
|
|
491
|
+
|
|
492
|
+
# Show missing tools
|
|
493
|
+
print_warning "Missing quality tools: ${missing_tools[*]}"
|
|
494
|
+
print_info "These tools are used by linters-local.sh for code quality checks"
|
|
495
|
+
|
|
496
|
+
# In non-interactive mode, just warn and continue
|
|
497
|
+
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
|
498
|
+
print_info "Install later: brew install ${missing_tools[*]}"
|
|
499
|
+
return 0
|
|
500
|
+
fi
|
|
501
|
+
|
|
502
|
+
# Offer to install
|
|
503
|
+
local pkg_manager
|
|
504
|
+
pkg_manager=$(detect_package_manager)
|
|
505
|
+
|
|
506
|
+
if [[ "$pkg_manager" == "unknown" ]]; then
|
|
507
|
+
print_info "Install manually:"
|
|
508
|
+
echo " macOS: brew install ${missing_tools[*]}"
|
|
509
|
+
echo " Ubuntu/Debian: sudo apt-get install ${missing_tools[*]}"
|
|
510
|
+
echo " Fedora: sudo dnf install ${missing_tools[*]}"
|
|
511
|
+
return 0
|
|
512
|
+
fi
|
|
513
|
+
|
|
514
|
+
echo ""
|
|
515
|
+
read -r -p "Install quality tools using $pkg_manager? [Y/n]: " install_quality
|
|
516
|
+
|
|
517
|
+
if [[ "$install_quality" =~ ^[Yy]?$ ]]; then
|
|
518
|
+
print_info "Installing ${missing_tools[*]}..."
|
|
519
|
+
if install_packages "$pkg_manager" "${missing_tools[@]}"; then
|
|
520
|
+
print_success "Quality tools installed successfully"
|
|
521
|
+
else
|
|
522
|
+
print_warning "Failed to install some quality tools - continuing anyway"
|
|
523
|
+
fi
|
|
524
|
+
else
|
|
525
|
+
print_info "Skipped quality tools installation"
|
|
526
|
+
print_info "Install later: $pkg_manager install ${missing_tools[*]}"
|
|
527
|
+
fi
|
|
528
|
+
|
|
529
|
+
return 0
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
verify_location() {
|
|
533
|
+
local current_dir
|
|
534
|
+
current_dir="$(pwd)"
|
|
535
|
+
local expected_location="$HOME/Git/aidevops"
|
|
536
|
+
|
|
537
|
+
if [[ "$current_dir" != "$expected_location" ]]; then
|
|
538
|
+
print_warning "Repository is not in the recommended location"
|
|
539
|
+
print_info "Current location: $current_dir"
|
|
540
|
+
print_info "Recommended location: $expected_location"
|
|
541
|
+
echo ""
|
|
542
|
+
echo "For optimal AI assistant integration, consider moving this repository to:"
|
|
543
|
+
echo " mkdir -p ~/git"
|
|
544
|
+
echo " mv '$current_dir' '$expected_location'"
|
|
545
|
+
echo ""
|
|
546
|
+
else
|
|
547
|
+
print_success "Repository is in the recommended location: $expected_location"
|
|
548
|
+
fi
|
|
549
|
+
return 0
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
set_permissions() {
|
|
553
|
+
print_info "Setting proper file permissions..."
|
|
554
|
+
|
|
555
|
+
local deployed_dir="$HOME/.aidevops/agents"
|
|
556
|
+
|
|
557
|
+
# Set permissions on DEPLOYED agents (not the git repo, to avoid dirtying the working tree)
|
|
558
|
+
# See: https://github.com/marcusquinn/aidevops/issues/2286
|
|
559
|
+
if [[ -d "$deployed_dir/scripts" ]]; then
|
|
560
|
+
chmod +x "$deployed_dir/scripts/"*.sh 2>/dev/null || true
|
|
561
|
+
# Also handle modularised subdirectories (e.g. memory/, supervisor-modules/)
|
|
562
|
+
find "$deployed_dir/scripts" -mindepth 2 -name "*.sh" -exec chmod +x {} + 2>/dev/null || true
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
# Secure configuration files (these are in the user's config dir, not the repo)
|
|
566
|
+
chmod 600 "$HOME/.config/aidevops/"*.json 2>/dev/null || true
|
|
567
|
+
# Also secure repo-local configs if present (for interactive setup from repo root)
|
|
568
|
+
chmod 600 configs/*.json 2>/dev/null || true
|
|
569
|
+
|
|
570
|
+
print_success "File permissions set"
|
|
571
|
+
return 0
|
|
572
|
+
}
|