aidevops 2.100.6 → 2.100.8
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 +1 -1
- package/setup.sh +200 -134
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.100.
|
|
1
|
+
2.100.8
|
package/aidevops.sh
CHANGED
package/package.json
CHANGED
package/setup.sh
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# AI Assistant Server Access Framework Setup Script
|
|
4
4
|
# Helps developers set up the framework for their infrastructure
|
|
5
5
|
#
|
|
6
|
-
# Version: 2.100.
|
|
6
|
+
# Version: 2.100.8
|
|
7
7
|
#
|
|
8
8
|
# Quick Install (one-liner):
|
|
9
9
|
# bash <(curl -fsSL https://aidevops.dev/install)
|
|
@@ -28,6 +28,41 @@ print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
|
|
28
28
|
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
|
29
29
|
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
30
30
|
|
|
31
|
+
# Spinner for long-running operations
|
|
32
|
+
# Usage: run_with_spinner "Installing package..." command arg1 arg2
|
|
33
|
+
run_with_spinner() {
|
|
34
|
+
local message="$1"
|
|
35
|
+
shift
|
|
36
|
+
local pid
|
|
37
|
+
local spin_chars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
|
|
38
|
+
local i=0
|
|
39
|
+
|
|
40
|
+
# Start command in background
|
|
41
|
+
"$@" &>/dev/null &
|
|
42
|
+
pid=$!
|
|
43
|
+
|
|
44
|
+
# Show spinner while command runs
|
|
45
|
+
printf "${BLUE}[INFO]${NC} %s " "$message"
|
|
46
|
+
while kill -0 "$pid" 2>/dev/null; do
|
|
47
|
+
printf "\r${BLUE}[INFO]${NC} %s %s" "$message" "${spin_chars:i++%${#spin_chars}:1}"
|
|
48
|
+
sleep 0.1
|
|
49
|
+
done
|
|
50
|
+
|
|
51
|
+
# Check exit status
|
|
52
|
+
wait "$pid"
|
|
53
|
+
local exit_code=$?
|
|
54
|
+
|
|
55
|
+
# Clear spinner and show result
|
|
56
|
+
printf "\r"
|
|
57
|
+
if [[ $exit_code -eq 0 ]]; then
|
|
58
|
+
print_success "$message done"
|
|
59
|
+
else
|
|
60
|
+
print_error "$message failed"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
return $exit_code
|
|
64
|
+
}
|
|
65
|
+
|
|
31
66
|
# Find OpenCode config file (checks multiple possible locations)
|
|
32
67
|
# Returns: path to config file, or empty string if not found
|
|
33
68
|
find_opencode_config() {
|
|
@@ -377,6 +412,85 @@ disable_ondemand_mcps() {
|
|
|
377
412
|
return 0
|
|
378
413
|
}
|
|
379
414
|
|
|
415
|
+
# Validate and repair OpenCode config schema
|
|
416
|
+
# Fixes common issues from manual editing or AI-generated configs:
|
|
417
|
+
# - MCP entries missing "type": "local" field
|
|
418
|
+
# - tools entries as objects {} instead of booleans
|
|
419
|
+
# If invalid, backs up and regenerates using the generator script
|
|
420
|
+
validate_opencode_config() {
|
|
421
|
+
local opencode_config
|
|
422
|
+
opencode_config=$(find_opencode_config) || return 0
|
|
423
|
+
|
|
424
|
+
if [[ ! -f "$opencode_config" ]]; then
|
|
425
|
+
return 0
|
|
426
|
+
fi
|
|
427
|
+
|
|
428
|
+
if ! command -v jq &> /dev/null; then
|
|
429
|
+
return 0
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
local needs_repair=false
|
|
433
|
+
local issues=""
|
|
434
|
+
|
|
435
|
+
# Check 1: MCP entries must have "type" field (usually "local")
|
|
436
|
+
# Invalid: {"mcp": {"foo": {"command": "..."}}}
|
|
437
|
+
# Valid: {"mcp": {"foo": {"type": "local", "command": "..."}}}
|
|
438
|
+
local mcps_without_type
|
|
439
|
+
mcps_without_type=$(jq -r '.mcp // {} | to_entries[] | select(.value.type == null and .value.command != null) | .key' "$opencode_config" 2>/dev/null | head -5)
|
|
440
|
+
if [[ -n "$mcps_without_type" ]]; then
|
|
441
|
+
needs_repair=true
|
|
442
|
+
issues="${issues}\n - MCP entries missing 'type' field: $(echo "$mcps_without_type" | tr '\n' ', ' | sed 's/,$//')"
|
|
443
|
+
fi
|
|
444
|
+
|
|
445
|
+
# Check 2: tools entries must be booleans, not objects
|
|
446
|
+
# Invalid: {"tools": {"gh_grep": {}}}
|
|
447
|
+
# Valid: {"tools": {"gh_grep": true}}
|
|
448
|
+
local tools_as_objects
|
|
449
|
+
tools_as_objects=$(jq -r '.tools // {} | to_entries[] | select(.value | type == "object") | .key' "$opencode_config" 2>/dev/null | head -5)
|
|
450
|
+
if [[ -n "$tools_as_objects" ]]; then
|
|
451
|
+
needs_repair=true
|
|
452
|
+
issues="${issues}\n - tools entries as objects instead of booleans: $(echo "$tools_as_objects" | tr '\n' ', ' | sed 's/,$//')"
|
|
453
|
+
fi
|
|
454
|
+
|
|
455
|
+
# Check 3: Try to parse with opencode (if available) to catch other schema issues
|
|
456
|
+
if command -v opencode &> /dev/null; then
|
|
457
|
+
local validation_output
|
|
458
|
+
if ! validation_output=$(opencode --version 2>&1); then
|
|
459
|
+
# If opencode fails to start, config might be invalid
|
|
460
|
+
if echo "$validation_output" | grep -q "Configuration is invalid"; then
|
|
461
|
+
needs_repair=true
|
|
462
|
+
issues="${issues}\n - OpenCode reports invalid configuration"
|
|
463
|
+
fi
|
|
464
|
+
fi
|
|
465
|
+
fi
|
|
466
|
+
|
|
467
|
+
if [[ "$needs_repair" == "true" ]]; then
|
|
468
|
+
print_warning "OpenCode config has schema issues:$issues"
|
|
469
|
+
|
|
470
|
+
# Backup the invalid config
|
|
471
|
+
create_backup_with_rotation "$opencode_config" "opencode"
|
|
472
|
+
print_info "Backed up invalid config"
|
|
473
|
+
|
|
474
|
+
# Remove the invalid config so generator creates fresh one
|
|
475
|
+
rm -f "$opencode_config"
|
|
476
|
+
|
|
477
|
+
# Regenerate using the generator script
|
|
478
|
+
local generator_script="$HOME/.aidevops/agents/scripts/generate-opencode-agents.sh"
|
|
479
|
+
if [[ -x "$generator_script" ]]; then
|
|
480
|
+
print_info "Regenerating OpenCode config with correct schema..."
|
|
481
|
+
if "$generator_script" > /dev/null 2>&1; then
|
|
482
|
+
print_success "OpenCode config regenerated successfully"
|
|
483
|
+
else
|
|
484
|
+
print_warning "Config regeneration failed - run manually: $generator_script"
|
|
485
|
+
fi
|
|
486
|
+
else
|
|
487
|
+
print_warning "Generator script not found - run setup.sh again after agents are deployed"
|
|
488
|
+
fi
|
|
489
|
+
fi
|
|
490
|
+
|
|
491
|
+
return 0
|
|
492
|
+
}
|
|
493
|
+
|
|
380
494
|
# Migrate old config-backups to new per-type backup structure
|
|
381
495
|
# This runs once to clean up the legacy backup directory
|
|
382
496
|
migrate_old_backups() {
|
|
@@ -660,9 +774,9 @@ check_requirements() {
|
|
|
660
774
|
fi
|
|
661
775
|
|
|
662
776
|
echo ""
|
|
663
|
-
read -r -p "Install missing dependencies using $pkg_manager?
|
|
777
|
+
read -r -p "Install missing dependencies using $pkg_manager? [Y/n]: " install_deps
|
|
664
778
|
|
|
665
|
-
if [[ "$install_deps"
|
|
779
|
+
if [[ "$install_deps" =~ ^[Yy]?$ ]]; then
|
|
666
780
|
print_info "Installing ${missing_deps[*]}..."
|
|
667
781
|
if install_packages "$pkg_manager" "${missing_deps[@]}"; then
|
|
668
782
|
print_success "Dependencies installed successfully"
|
|
@@ -699,9 +813,9 @@ check_optional_deps() {
|
|
|
699
813
|
pkg_manager=$(detect_package_manager)
|
|
700
814
|
|
|
701
815
|
if [[ "$pkg_manager" != "unknown" ]]; then
|
|
702
|
-
read -r -p "Install optional dependencies using $pkg_manager?
|
|
816
|
+
read -r -p "Install optional dependencies using $pkg_manager? [Y/n]: " install_optional
|
|
703
817
|
|
|
704
|
-
if [[ "$install_optional"
|
|
818
|
+
if [[ "$install_optional" =~ ^[Yy]?$ ]]; then
|
|
705
819
|
print_info "Installing ${missing_optional[*]}..."
|
|
706
820
|
if install_packages "$pkg_manager" "${missing_optional[@]}"; then
|
|
707
821
|
print_success "Optional dependencies installed"
|
|
@@ -755,9 +869,9 @@ setup_git_clis() {
|
|
|
755
869
|
|
|
756
870
|
if [[ "$pkg_manager" != "unknown" ]]; then
|
|
757
871
|
echo ""
|
|
758
|
-
read -r -p "Install Git CLI tools (${missing_packages[*]}) using $pkg_manager?
|
|
872
|
+
read -r -p "Install Git CLI tools (${missing_packages[*]}) using $pkg_manager? [Y/n]: " install_git_clis
|
|
759
873
|
|
|
760
|
-
if [[ "$install_git_clis"
|
|
874
|
+
if [[ "$install_git_clis" =~ ^[Yy]?$ ]]; then
|
|
761
875
|
print_info "Installing ${missing_packages[*]}..."
|
|
762
876
|
if install_packages "$pkg_manager" "${missing_packages[@]}"; then
|
|
763
877
|
print_success "Git CLI tools installed"
|
|
@@ -853,10 +967,10 @@ setup_file_discovery_tools() {
|
|
|
853
967
|
if [[ "$pkg_manager" != "unknown" ]]; then
|
|
854
968
|
local install_fd_tools="y"
|
|
855
969
|
if [[ "$INTERACTIVE_MODE" == "true" ]]; then
|
|
856
|
-
read -r -p "Install file discovery tools (${missing_packages[*]}) using $pkg_manager?
|
|
970
|
+
read -r -p "Install file discovery tools (${missing_packages[*]}) using $pkg_manager? [Y/n]: " install_fd_tools
|
|
857
971
|
fi
|
|
858
972
|
|
|
859
|
-
if [[ "$install_fd_tools"
|
|
973
|
+
if [[ "$install_fd_tools" =~ ^[Yy]?$ ]]; then
|
|
860
974
|
print_info "Installing ${missing_packages[*]}..."
|
|
861
975
|
|
|
862
976
|
# Handle package name differences across package managers
|
|
@@ -959,8 +1073,8 @@ setup_worktrunk() {
|
|
|
959
1073
|
if [[ -n "$shell_rc" ]] && [[ -f "$shell_rc" ]]; then
|
|
960
1074
|
if ! grep -q "worktrunk" "$shell_rc" 2>/dev/null; then
|
|
961
1075
|
print_info "Shell integration not detected"
|
|
962
|
-
read -r -p "Install Worktrunk shell integration (enables 'wt switch' to change directories)?
|
|
963
|
-
if [[ "$install_shell"
|
|
1076
|
+
read -r -p "Install Worktrunk shell integration (enables 'wt switch' to change directories)? [Y/n]: " install_shell
|
|
1077
|
+
if [[ "$install_shell" =~ ^[Yy]?$ ]]; then
|
|
964
1078
|
if wt config shell install 2>/dev/null; then
|
|
965
1079
|
print_success "Shell integration installed"
|
|
966
1080
|
print_info "Restart your terminal or run: source $shell_rc"
|
|
@@ -989,25 +1103,15 @@ setup_worktrunk() {
|
|
|
989
1103
|
pkg_manager=$(detect_package_manager)
|
|
990
1104
|
|
|
991
1105
|
if [[ "$pkg_manager" == "brew" ]]; then
|
|
992
|
-
read -r -p "Install Worktrunk via Homebrew?
|
|
1106
|
+
read -r -p "Install Worktrunk via Homebrew? [Y/n]: " install_wt
|
|
993
1107
|
|
|
994
|
-
if [[ "$install_wt"
|
|
995
|
-
|
|
996
|
-
if brew install max-sixty/worktrunk/wt 2>/dev/null; then
|
|
997
|
-
print_success "Worktrunk installed"
|
|
998
|
-
|
|
1108
|
+
if [[ "$install_wt" =~ ^[Yy]?$ ]]; then
|
|
1109
|
+
if run_with_spinner "Installing Worktrunk via Homebrew" brew install max-sixty/worktrunk/wt; then
|
|
999
1110
|
# Install shell integration
|
|
1000
|
-
|
|
1001
|
-
local wt_shell_output
|
|
1002
|
-
if wt_shell_output=$(wt config shell install 2>&1); then
|
|
1003
|
-
print_success "Shell integration installed"
|
|
1111
|
+
if run_with_spinner "Installing shell integration" wt config shell install; then
|
|
1004
1112
|
print_info "Restart your terminal or source your shell config"
|
|
1005
1113
|
else
|
|
1006
|
-
# Show the actual error for debugging
|
|
1007
1114
|
print_warning "Shell integration failed - run manually: wt config shell install"
|
|
1008
|
-
if [[ -n "$wt_shell_output" ]]; then
|
|
1009
|
-
echo "$wt_shell_output" | head -3 | sed 's/^/ /'
|
|
1010
|
-
fi
|
|
1011
1115
|
fi
|
|
1012
1116
|
|
|
1013
1117
|
echo ""
|
|
@@ -1027,16 +1131,13 @@ setup_worktrunk() {
|
|
|
1027
1131
|
print_info "Fallback available: ~/.aidevops/agents/scripts/worktree-helper.sh"
|
|
1028
1132
|
fi
|
|
1029
1133
|
elif command -v cargo >/dev/null 2>&1; then
|
|
1030
|
-
read -r -p "Install Worktrunk via Cargo?
|
|
1134
|
+
read -r -p "Install Worktrunk via Cargo? [Y/n]: " install_wt
|
|
1031
1135
|
|
|
1032
|
-
if [[ "$install_wt"
|
|
1033
|
-
|
|
1034
|
-
if cargo install worktrunk 2>/dev/null; then
|
|
1035
|
-
print_success "Worktrunk installed"
|
|
1036
|
-
|
|
1136
|
+
if [[ "$install_wt" =~ ^[Yy]?$ ]]; then
|
|
1137
|
+
if run_with_spinner "Installing Worktrunk via Cargo" cargo install worktrunk; then
|
|
1037
1138
|
# Install shell integration
|
|
1038
|
-
if wt config shell install
|
|
1039
|
-
|
|
1139
|
+
if run_with_spinner "Installing shell integration" wt config shell install; then
|
|
1140
|
+
print_info "Restart your terminal or source your shell config"
|
|
1040
1141
|
else
|
|
1041
1142
|
print_warning "Shell integration failed - run manually: wt config shell install"
|
|
1042
1143
|
fi
|
|
@@ -1121,8 +1222,8 @@ setup_recommended_tools() {
|
|
|
1121
1222
|
|
|
1122
1223
|
if [[ -d "$zed_extensions_dir" ]]; then
|
|
1123
1224
|
if [[ ! -d "$zed_extensions_dir/opencode" ]]; then
|
|
1124
|
-
read -r -p "Install OpenCode extension for Zed?
|
|
1125
|
-
if [[ "$install_opencode_ext"
|
|
1225
|
+
read -r -p "Install OpenCode extension for Zed? [Y/n]: " install_opencode_ext
|
|
1226
|
+
if [[ "$install_opencode_ext" =~ ^[Yy]?$ ]]; then
|
|
1126
1227
|
print_info "Installing OpenCode extension..."
|
|
1127
1228
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
1128
1229
|
open "zed://extension/opencode" 2>/dev/null
|
|
@@ -1148,15 +1249,13 @@ setup_recommended_tools() {
|
|
|
1148
1249
|
|
|
1149
1250
|
# Install Tabby if missing
|
|
1150
1251
|
if [[ " ${missing_tools[*]} " =~ " tabby " ]]; then
|
|
1151
|
-
read -r -p "Install Tabby terminal?
|
|
1252
|
+
read -r -p "Install Tabby terminal? [Y/n]: " install_tabby
|
|
1152
1253
|
|
|
1153
|
-
if [[ "$install_tabby"
|
|
1154
|
-
print_info "Installing Tabby..."
|
|
1254
|
+
if [[ "$install_tabby" =~ ^[Yy]?$ ]]; then
|
|
1155
1255
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
1156
1256
|
if command -v brew >/dev/null 2>&1; then
|
|
1157
|
-
brew install --cask tabby
|
|
1158
|
-
|
|
1159
|
-
print_success "Tabby installed successfully"
|
|
1257
|
+
if run_with_spinner "Installing Tabby" brew install --cask tabby; then
|
|
1258
|
+
: # Success message handled by spinner
|
|
1160
1259
|
else
|
|
1161
1260
|
print_warning "Failed to install Tabby via Homebrew"
|
|
1162
1261
|
echo " Download manually: https://github.com/Eugeny/tabby/releases/latest"
|
|
@@ -1197,16 +1296,13 @@ setup_recommended_tools() {
|
|
|
1197
1296
|
|
|
1198
1297
|
# Install Zed if missing
|
|
1199
1298
|
if [[ " ${missing_tools[*]} " =~ " zed " ]]; then
|
|
1200
|
-
read -r -p "Install Zed editor?
|
|
1299
|
+
read -r -p "Install Zed editor? [Y/n]: " install_zed
|
|
1201
1300
|
|
|
1202
|
-
if [[ "$install_zed"
|
|
1203
|
-
print_info "Installing Zed..."
|
|
1301
|
+
if [[ "$install_zed" =~ ^[Yy]?$ ]]; then
|
|
1204
1302
|
local zed_installed=false
|
|
1205
1303
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
1206
1304
|
if command -v brew >/dev/null 2>&1; then
|
|
1207
|
-
brew install --cask zed
|
|
1208
|
-
if [[ $? -eq 0 ]]; then
|
|
1209
|
-
print_success "Zed installed successfully"
|
|
1305
|
+
if run_with_spinner "Installing Zed" brew install --cask zed; then
|
|
1210
1306
|
zed_installed=true
|
|
1211
1307
|
else
|
|
1212
1308
|
print_warning "Failed to install Zed via Homebrew"
|
|
@@ -1217,10 +1313,9 @@ setup_recommended_tools() {
|
|
|
1217
1313
|
echo " Download manually: https://zed.dev/download"
|
|
1218
1314
|
fi
|
|
1219
1315
|
elif [[ "$(uname)" == "Linux" ]]; then
|
|
1220
|
-
# Zed provides an install script for Linux
|
|
1316
|
+
# Zed provides an install script for Linux (interactive, can't use spinner)
|
|
1221
1317
|
print_info "Running Zed install script..."
|
|
1222
|
-
curl -f https://zed.dev/install.sh | sh
|
|
1223
|
-
if [[ $? -eq 0 ]]; then
|
|
1318
|
+
if curl -f https://zed.dev/install.sh | sh; then
|
|
1224
1319
|
print_success "Zed installed successfully"
|
|
1225
1320
|
zed_installed=true
|
|
1226
1321
|
else
|
|
@@ -1231,8 +1326,8 @@ setup_recommended_tools() {
|
|
|
1231
1326
|
|
|
1232
1327
|
# Install OpenCode extension for Zed
|
|
1233
1328
|
if [[ "$zed_installed" == "true" ]]; then
|
|
1234
|
-
read -r -p "Install OpenCode extension for Zed?
|
|
1235
|
-
if [[ "$install_opencode_ext"
|
|
1329
|
+
read -r -p "Install OpenCode extension for Zed? [Y/n]: " install_opencode_ext
|
|
1330
|
+
if [[ "$install_opencode_ext" =~ ^[Yy]?$ ]]; then
|
|
1236
1331
|
print_info "Installing OpenCode extension..."
|
|
1237
1332
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
1238
1333
|
open "zed://extension/opencode" 2>/dev/null
|
|
@@ -1319,12 +1414,10 @@ setup_minisim() {
|
|
|
1319
1414
|
fi
|
|
1320
1415
|
|
|
1321
1416
|
local install_minisim
|
|
1322
|
-
read -r -p "Install MiniSim?
|
|
1417
|
+
read -r -p "Install MiniSim? [Y/n]: " install_minisim
|
|
1323
1418
|
|
|
1324
|
-
if [[ "$install_minisim"
|
|
1325
|
-
|
|
1326
|
-
if brew install --cask minisim; then
|
|
1327
|
-
print_success "MiniSim installed successfully"
|
|
1419
|
+
if [[ "$install_minisim" =~ ^[Yy]?$ ]]; then
|
|
1420
|
+
if run_with_spinner "Installing MiniSim" brew install --cask minisim; then
|
|
1328
1421
|
print_info "Global shortcut: Option + Shift + E"
|
|
1329
1422
|
print_info "Documentation: ~/.aidevops/agents/tools/mobile/minisim.md"
|
|
1330
1423
|
else
|
|
@@ -1345,9 +1438,9 @@ setup_ssh_key() {
|
|
|
1345
1438
|
|
|
1346
1439
|
if [[ ! -f ~/.ssh/id_ed25519 ]]; then
|
|
1347
1440
|
print_warning "Ed25519 SSH key not found"
|
|
1348
|
-
read -r -p "Generate new Ed25519 SSH key?
|
|
1441
|
+
read -r -p "Generate new Ed25519 SSH key? [Y/n]: " generate_key
|
|
1349
1442
|
|
|
1350
|
-
if [[ "$generate_key"
|
|
1443
|
+
if [[ "$generate_key" =~ ^[Yy]?$ ]]; then
|
|
1351
1444
|
read -r -p "Enter your email address: " email
|
|
1352
1445
|
ssh-keygen -t ed25519 -C "$email"
|
|
1353
1446
|
print_success "SSH key generated"
|
|
@@ -1563,9 +1656,9 @@ setup_aliases() {
|
|
|
1563
1656
|
fi
|
|
1564
1657
|
|
|
1565
1658
|
print_info "Detected shell: $shell_name"
|
|
1566
|
-
read -r -p "Add shell aliases to $shell_rc?
|
|
1659
|
+
read -r -p "Add shell aliases to $shell_rc? [Y/n]: " add_aliases
|
|
1567
1660
|
|
|
1568
|
-
if [[ "$add_aliases"
|
|
1661
|
+
if [[ "$add_aliases" =~ ^[Yy]?$ ]]; then
|
|
1569
1662
|
# Fish shell uses different syntax
|
|
1570
1663
|
if [[ "$shell_name" == "fish" ]]; then
|
|
1571
1664
|
mkdir -p "$HOME/.config/fish"
|
|
@@ -1652,9 +1745,9 @@ setup_terminal_title() {
|
|
|
1652
1745
|
fi
|
|
1653
1746
|
|
|
1654
1747
|
echo ""
|
|
1655
|
-
read -r -p "Install terminal title integration?
|
|
1748
|
+
read -r -p "Install terminal title integration? [Y/n]: " install_title
|
|
1656
1749
|
|
|
1657
|
-
if [[ "$install_title"
|
|
1750
|
+
if [[ "$install_title" =~ ^[Yy]?$ ]]; then
|
|
1658
1751
|
if bash "$setup_script" install; then
|
|
1659
1752
|
print_success "Terminal title integration installed"
|
|
1660
1753
|
else
|
|
@@ -2182,14 +2275,9 @@ setup_python_env() {
|
|
|
2182
2275
|
source python-env/dspy-env/bin/activate
|
|
2183
2276
|
pip install --upgrade pip > /dev/null 2>&1
|
|
2184
2277
|
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
print_success "DSPy dependencies installed successfully"
|
|
2278
|
+
if run_with_spinner "Installing DSPy dependencies" pip install -r requirements.txt; then
|
|
2279
|
+
: # Success message handled by spinner
|
|
2188
2280
|
else
|
|
2189
|
-
print_warning "Failed to install DSPy dependencies:"
|
|
2190
|
-
# Show last few lines of error for debugging
|
|
2191
|
-
echo "$pip_output" | tail -8 | sed 's/^/ /'
|
|
2192
|
-
echo ""
|
|
2193
2281
|
print_info "Check requirements.txt or run manually:"
|
|
2194
2282
|
print_info " source python-env/dspy-env/bin/activate && pip install -r requirements.txt"
|
|
2195
2283
|
fi
|
|
@@ -2220,13 +2308,10 @@ setup_nodejs_env() {
|
|
|
2220
2308
|
|
|
2221
2309
|
# Install DSPyGround globally if not already installed
|
|
2222
2310
|
if ! command -v dspyground &> /dev/null; then
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
if [[ $? -eq 0 ]]; then
|
|
2227
|
-
print_success "DSPyGround installed successfully"
|
|
2311
|
+
if run_with_spinner "Installing DSPyGround" npm install -g dspyground; then
|
|
2312
|
+
: # Success message handled by spinner
|
|
2228
2313
|
else
|
|
2229
|
-
print_warning "
|
|
2314
|
+
print_warning "Try manually: npm install -g dspyground"
|
|
2230
2315
|
fi
|
|
2231
2316
|
else
|
|
2232
2317
|
print_success "DSPyGround already installed"
|
|
@@ -2462,16 +2547,13 @@ setup_localwp_mcp() {
|
|
|
2462
2547
|
|
|
2463
2548
|
# Offer to install mcp-local-wp
|
|
2464
2549
|
print_info "LocalWP MCP server enables AI assistants to query WordPress databases"
|
|
2465
|
-
read -r -p "Install LocalWP MCP server (@verygoodplugins/mcp-local-wp)?
|
|
2550
|
+
read -r -p "Install LocalWP MCP server (@verygoodplugins/mcp-local-wp)? [Y/n]: " install_mcp
|
|
2466
2551
|
|
|
2467
|
-
if [[ "$install_mcp"
|
|
2468
|
-
|
|
2469
|
-
if npm install -g @verygoodplugins/mcp-local-wp > /dev/null 2>&1; then
|
|
2470
|
-
print_success "LocalWP MCP server installed successfully"
|
|
2552
|
+
if [[ "$install_mcp" =~ ^[Yy]?$ ]]; then
|
|
2553
|
+
if run_with_spinner "Installing LocalWP MCP server" npm install -g @verygoodplugins/mcp-local-wp; then
|
|
2471
2554
|
print_info "Start with: ~/.aidevops/agents/scripts/localhost-helper.sh start-mcp"
|
|
2472
2555
|
print_info "Or configure in OpenCode MCP settings for auto-start"
|
|
2473
2556
|
else
|
|
2474
|
-
print_warning "Failed to install LocalWP MCP server"
|
|
2475
2557
|
print_info "Try manually: npm install -g @verygoodplugins/mcp-local-wp"
|
|
2476
2558
|
fi
|
|
2477
2559
|
else
|
|
@@ -2580,16 +2662,13 @@ setup_beads() {
|
|
|
2580
2662
|
else
|
|
2581
2663
|
# Try to install via Homebrew first (macOS/Linux with Homebrew)
|
|
2582
2664
|
if command -v brew &> /dev/null; then
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
print_success "Beads CLI installed via Homebrew"
|
|
2665
|
+
if run_with_spinner "Installing Beads via Homebrew" brew install steveyegge/beads/bd; then
|
|
2666
|
+
: # Success message handled by spinner
|
|
2586
2667
|
else
|
|
2587
2668
|
print_warning "Homebrew tap installation failed, trying alternative..."
|
|
2588
2669
|
# Try Go install if Go is available
|
|
2589
2670
|
if command -v go &> /dev/null; then
|
|
2590
|
-
|
|
2591
|
-
if go install github.com/steveyegge/beads/cmd/bd@latest 2>/dev/null; then
|
|
2592
|
-
print_success "Beads CLI installed via Go"
|
|
2671
|
+
if run_with_spinner "Installing Beads via Go" go install github.com/steveyegge/beads/cmd/bd@latest; then
|
|
2593
2672
|
print_info "Ensure \$GOPATH/bin is in your PATH"
|
|
2594
2673
|
else
|
|
2595
2674
|
print_warning "Go installation failed"
|
|
@@ -2597,9 +2676,7 @@ setup_beads() {
|
|
|
2597
2676
|
fi
|
|
2598
2677
|
fi
|
|
2599
2678
|
elif command -v go &> /dev/null; then
|
|
2600
|
-
|
|
2601
|
-
if go install github.com/steveyegge/beads/cmd/bd@latest 2>/dev/null; then
|
|
2602
|
-
print_success "Beads CLI installed via Go"
|
|
2679
|
+
if run_with_spinner "Installing Beads via Go" go install github.com/steveyegge/beads/cmd/bd@latest; then
|
|
2603
2680
|
print_info "Ensure \$GOPATH/bin is in your PATH"
|
|
2604
2681
|
else
|
|
2605
2682
|
print_warning "Go installation failed"
|
|
@@ -2635,9 +2712,9 @@ setup_beads_ui() {
|
|
|
2635
2712
|
echo " • perles (Rust) - BQL query language TUI"
|
|
2636
2713
|
echo ""
|
|
2637
2714
|
|
|
2638
|
-
read -r -p "Install optional Beads UI tools?
|
|
2715
|
+
read -r -p "Install optional Beads UI tools? [Y/n]: " install_beads_ui
|
|
2639
2716
|
|
|
2640
|
-
if [[ "$install_beads_ui"
|
|
2717
|
+
if [[ ! "$install_beads_ui" =~ ^[Yy]?$ ]]; then
|
|
2641
2718
|
print_info "Skipped Beads UI tools (can install later from beads.md docs)"
|
|
2642
2719
|
return 0
|
|
2643
2720
|
fi
|
|
@@ -2646,24 +2723,21 @@ setup_beads_ui() {
|
|
|
2646
2723
|
|
|
2647
2724
|
# beads_viewer (Python) - use pipx for isolated install
|
|
2648
2725
|
if command -v pipx &> /dev/null || command -v pip3 &> /dev/null || command -v pip &> /dev/null; then
|
|
2649
|
-
read -r -p " Install beads_viewer (Python TUI with graph analytics)?
|
|
2650
|
-
if [[ "$install_viewer"
|
|
2726
|
+
read -r -p " Install beads_viewer (Python TUI with graph analytics)? [Y/n]: " install_viewer
|
|
2727
|
+
if [[ "$install_viewer" =~ ^[Yy]?$ ]]; then
|
|
2651
2728
|
if command -v pipx &> /dev/null; then
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
print_success "beads_viewer installed (run: beads-viewer)"
|
|
2729
|
+
if run_with_spinner "Installing beads_viewer via pipx" pipx install beads-viewer; then
|
|
2730
|
+
print_info "Run: beads-viewer"
|
|
2655
2731
|
((installed_count++))
|
|
2656
2732
|
else
|
|
2657
|
-
print_warning "Failed to install beads_viewer"
|
|
2658
2733
|
print_info "Try manually: pipx install beads-viewer"
|
|
2659
2734
|
fi
|
|
2660
2735
|
else
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2736
|
+
if run_with_spinner "Installing beads_viewer" pip3 install --user beads-viewer; then
|
|
2737
|
+
((installed_count++))
|
|
2738
|
+
elif run_with_spinner "Installing beads_viewer" pip install --user beads-viewer; then
|
|
2664
2739
|
((installed_count++))
|
|
2665
2740
|
else
|
|
2666
|
-
print_warning "Failed to install beads_viewer"
|
|
2667
2741
|
print_info "On macOS, install pipx first: brew install pipx && pipx ensurepath"
|
|
2668
2742
|
fi
|
|
2669
2743
|
fi
|
|
@@ -2672,39 +2746,30 @@ setup_beads_ui() {
|
|
|
2672
2746
|
|
|
2673
2747
|
# beads-ui (Node.js)
|
|
2674
2748
|
if command -v npm &> /dev/null; then
|
|
2675
|
-
read -r -p " Install beads-ui (Web dashboard)?
|
|
2676
|
-
if [[ "$install_web"
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
print_success "beads-ui installed (run: beads-ui)"
|
|
2749
|
+
read -r -p " Install beads-ui (Web dashboard)? [Y/n]: " install_web
|
|
2750
|
+
if [[ "$install_web" =~ ^[Yy]?$ ]]; then
|
|
2751
|
+
if run_with_spinner "Installing beads-ui" npm install -g beads-ui; then
|
|
2752
|
+
print_info "Run: beads-ui"
|
|
2680
2753
|
((installed_count++))
|
|
2681
|
-
else
|
|
2682
|
-
print_warning "Failed to install beads-ui"
|
|
2683
2754
|
fi
|
|
2684
2755
|
fi
|
|
2685
2756
|
|
|
2686
|
-
read -r -p " Install bdui (React/Ink TUI)?
|
|
2687
|
-
if [[ "$install_bdui"
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
print_success "bdui installed (run: bdui)"
|
|
2757
|
+
read -r -p " Install bdui (React/Ink TUI)? [Y/n]: " install_bdui
|
|
2758
|
+
if [[ "$install_bdui" =~ ^[Yy]?$ ]]; then
|
|
2759
|
+
if run_with_spinner "Installing bdui" npm install -g bdui; then
|
|
2760
|
+
print_info "Run: bdui"
|
|
2691
2761
|
((installed_count++))
|
|
2692
|
-
else
|
|
2693
|
-
print_warning "Failed to install bdui"
|
|
2694
2762
|
fi
|
|
2695
2763
|
fi
|
|
2696
2764
|
fi
|
|
2697
2765
|
|
|
2698
2766
|
# perles (Rust)
|
|
2699
2767
|
if command -v cargo &> /dev/null; then
|
|
2700
|
-
read -r -p " Install perles (BQL query language TUI)?
|
|
2701
|
-
if [[ "$install_perles"
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
print_success "perles installed (run: perles)"
|
|
2768
|
+
read -r -p " Install perles (BQL query language TUI)? [Y/n]: " install_perles
|
|
2769
|
+
if [[ "$install_perles" =~ ^[Yy]?$ ]]; then
|
|
2770
|
+
if run_with_spinner "Installing perles (Rust compile)" cargo install perles; then
|
|
2771
|
+
print_info "Run: perles"
|
|
2705
2772
|
((installed_count++))
|
|
2706
|
-
else
|
|
2707
|
-
print_warning "Failed to install perles"
|
|
2708
2773
|
fi
|
|
2709
2774
|
fi
|
|
2710
2775
|
fi
|
|
@@ -2795,9 +2860,9 @@ setup_browser_tools() {
|
|
|
2795
2860
|
print_success "Playwright already installed"
|
|
2796
2861
|
else
|
|
2797
2862
|
local install_playwright
|
|
2798
|
-
read -r -p "Install Playwright MCP with browsers (chromium, firefox, webkit)?
|
|
2863
|
+
read -r -p "Install Playwright MCP with browsers (chromium, firefox, webkit)? [Y/n]: " install_playwright
|
|
2799
2864
|
|
|
2800
|
-
if [[ "$install_playwright"
|
|
2865
|
+
if [[ "$install_playwright" =~ ^[Yy]?$ ]]; then
|
|
2801
2866
|
print_info "Installing Playwright browsers..."
|
|
2802
2867
|
# Use -y to auto-confirm npx install, suppress the "install without dependencies" warning
|
|
2803
2868
|
# Use PIPESTATUS to check npx exit code, not grep's exit code
|
|
@@ -3014,9 +3079,9 @@ setup_oh_my_opencode() {
|
|
|
3014
3079
|
echo " They are complementary and work well together."
|
|
3015
3080
|
echo ""
|
|
3016
3081
|
|
|
3017
|
-
read -r -p "Install Oh-My-OpenCode plugin?
|
|
3082
|
+
read -r -p "Install Oh-My-OpenCode plugin? [Y/n]: " install_omo
|
|
3018
3083
|
|
|
3019
|
-
if [[ "$install_omo"
|
|
3084
|
+
if [[ ! "$install_omo" =~ ^[Yy]?$ ]]; then
|
|
3020
3085
|
print_info "Skipped Oh-My-OpenCode installation"
|
|
3021
3086
|
return 0
|
|
3022
3087
|
fi
|
|
@@ -3267,10 +3332,10 @@ setup_multi_tenant_credentials() {
|
|
|
3267
3332
|
print_info "Everything continues to work as before - this is non-breaking."
|
|
3268
3333
|
echo ""
|
|
3269
3334
|
|
|
3270
|
-
read -r -p "Enable multi-tenant credential storage?
|
|
3335
|
+
read -r -p "Enable multi-tenant credential storage? [Y/n]: " enable_mt
|
|
3271
3336
|
enable_mt=$(echo "$enable_mt" | tr '[:upper:]' '[:lower:]')
|
|
3272
3337
|
|
|
3273
|
-
if [[ "$enable_mt"
|
|
3338
|
+
if [[ "$enable_mt" =~ ^[Yy]?$ || "$enable_mt" == "yes" ]]; then
|
|
3274
3339
|
bash "$credential_helper" init
|
|
3275
3340
|
print_success "Multi-tenant credential storage enabled"
|
|
3276
3341
|
echo ""
|
|
@@ -3332,9 +3397,9 @@ check_tool_updates() {
|
|
|
3332
3397
|
bash "$tool_check_script" --quiet
|
|
3333
3398
|
echo ""
|
|
3334
3399
|
|
|
3335
|
-
read -r -p "Update all outdated tools now?
|
|
3400
|
+
read -r -p "Update all outdated tools now? [Y/n]: " do_update
|
|
3336
3401
|
|
|
3337
|
-
if [[ "$do_update"
|
|
3402
|
+
if [[ "$do_update" =~ ^[Yy]?$ || "$do_update" == "Y" ]]; then
|
|
3338
3403
|
print_info "Updating tools..."
|
|
3339
3404
|
bash "$tool_check_script" --update
|
|
3340
3405
|
print_success "Tool updates complete!"
|
|
@@ -3432,6 +3497,7 @@ main() {
|
|
|
3432
3497
|
confirm_step "Migrate loop state from .claude/ to .agent/loop-state/" && migrate_loop_state_directories
|
|
3433
3498
|
confirm_step "Cleanup deprecated agent paths" && cleanup_deprecated_paths
|
|
3434
3499
|
confirm_step "Cleanup deprecated MCP entries (hetzner, serper, etc.)" && cleanup_deprecated_mcps
|
|
3500
|
+
confirm_step "Validate and repair OpenCode config schema" && validate_opencode_config
|
|
3435
3501
|
confirm_step "Extract OpenCode prompts" && extract_opencode_prompts
|
|
3436
3502
|
confirm_step "Check OpenCode prompt drift" && check_opencode_prompt_drift
|
|
3437
3503
|
confirm_step "Deploy aidevops agents to ~/.aidevops/agents/" && deploy_aidevops_agents
|
|
@@ -3543,8 +3609,8 @@ echo " aidevops uninstall - Remove aidevops"
|
|
|
3543
3609
|
echo " • Get personalized recommendations based on your work"
|
|
3544
3610
|
echo " • Set up API keys and credentials interactively"
|
|
3545
3611
|
echo ""
|
|
3546
|
-
read -r -p "Launch OpenCode with /onboarding now?
|
|
3547
|
-
if [[ "$launch_onboarding"
|
|
3612
|
+
read -r -p "Launch OpenCode with /onboarding now? [Y/n]: " launch_onboarding
|
|
3613
|
+
if [[ "$launch_onboarding" =~ ^[Yy]?$ || "$launch_onboarding" == "Y" ]]; then
|
|
3548
3614
|
echo ""
|
|
3549
3615
|
echo "Starting OpenCode..."
|
|
3550
3616
|
opencode --prompt "/onboarding"
|