aidevops 2.105.2 → 2.105.5
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 +30 -14
- package/package.json +1 -1
- package/setup.sh +179 -62
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.105.
|
|
1
|
+
2.105.5
|
package/aidevops.sh
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# AI DevOps Framework CLI
|
|
4
4
|
# Usage: aidevops <command> [options]
|
|
5
5
|
#
|
|
6
|
-
# Version: 2.105.
|
|
6
|
+
# Version: 2.105.5
|
|
7
7
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
|
|
@@ -25,6 +25,9 @@ REPOS_FILE="$CONFIG_DIR/repos.json"
|
|
|
25
25
|
REPO_URL="https://github.com/marcusquinn/aidevops.git"
|
|
26
26
|
VERSION_FILE="$INSTALL_DIR/VERSION"
|
|
27
27
|
|
|
28
|
+
# Portable sed in-place edit (macOS BSD sed vs GNU sed)
|
|
29
|
+
sed_inplace() { if [[ "$(uname)" == "Darwin" ]]; then sed -i '' "$@"; else sed -i "$@"; fi; }
|
|
30
|
+
|
|
28
31
|
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
29
32
|
print_success() { echo -e "${GREEN}[OK]${NC} $1"; }
|
|
30
33
|
print_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
@@ -588,8 +591,24 @@ cmd_update() {
|
|
|
588
591
|
fi
|
|
589
592
|
else
|
|
590
593
|
print_warning "Repository not found, performing fresh install..."
|
|
591
|
-
#
|
|
592
|
-
|
|
594
|
+
# Download setup script to temp file first (not piped to shell)
|
|
595
|
+
local tmp_setup
|
|
596
|
+
tmp_setup=$(mktemp "${TMPDIR:-/tmp}/aidevops-setup-XXXXXX.sh") || {
|
|
597
|
+
print_error "Failed to create temp file for setup script"
|
|
598
|
+
return 1
|
|
599
|
+
}
|
|
600
|
+
if curl -fsSL "https://raw.githubusercontent.com/marcusquinn/aidevops/main/setup.sh" -o "$tmp_setup" 2>/dev/null && [[ -s "$tmp_setup" ]]; then
|
|
601
|
+
chmod +x "$tmp_setup"
|
|
602
|
+
bash "$tmp_setup"
|
|
603
|
+
local setup_exit=$?
|
|
604
|
+
rm -f "$tmp_setup"
|
|
605
|
+
[[ $setup_exit -ne 0 ]] && return 1
|
|
606
|
+
else
|
|
607
|
+
rm -f "$tmp_setup"
|
|
608
|
+
print_error "Failed to download setup script"
|
|
609
|
+
print_info "Try: git clone https://github.com/marcusquinn/aidevops.git $INSTALL_DIR && bash $INSTALL_DIR/setup.sh"
|
|
610
|
+
return 1
|
|
611
|
+
fi
|
|
593
612
|
fi
|
|
594
613
|
|
|
595
614
|
# Check registered repos for updates
|
|
@@ -761,8 +780,7 @@ cmd_uninstall() {
|
|
|
761
780
|
# Create backup
|
|
762
781
|
cp "$rc_file" "$rc_file.bak"
|
|
763
782
|
# Remove our alias block (from comment to empty line)
|
|
764
|
-
|
|
765
|
-
rm -f "$rc_file.tmp"
|
|
783
|
+
sed_inplace '/# AI Assistant Server Access Framework/,/^$/d' "$rc_file"
|
|
766
784
|
print_success "Removed aliases from $rc_file"
|
|
767
785
|
fi
|
|
768
786
|
fi
|
|
@@ -798,7 +816,8 @@ cmd_uninstall() {
|
|
|
798
816
|
echo ""
|
|
799
817
|
print_success "Uninstall complete!"
|
|
800
818
|
print_info "To reinstall, run:"
|
|
801
|
-
echo "
|
|
819
|
+
echo " npm install -g aidevops && aidevops update"
|
|
820
|
+
echo " OR: brew install marcusquinn/tap/aidevops && aidevops update"
|
|
802
821
|
}
|
|
803
822
|
|
|
804
823
|
# Init command - initialize aidevops in a project
|
|
@@ -1360,8 +1379,7 @@ cmd_upgrade_planning() {
|
|
|
1360
1379
|
fi
|
|
1361
1380
|
|
|
1362
1381
|
# Update date placeholder
|
|
1363
|
-
|
|
1364
|
-
rm -f "${todo_file}.tmp"
|
|
1382
|
+
sed_inplace "s/{{DATE}}/$(date +%Y-%m-%d)/" "$todo_file" 2>/dev/null || true
|
|
1365
1383
|
|
|
1366
1384
|
# Merge existing tasks into Backlog section (after the TOON block closing tag)
|
|
1367
1385
|
if [[ -n "$existing_tasks" ]]; then
|
|
@@ -1426,8 +1444,7 @@ cmd_upgrade_planning() {
|
|
|
1426
1444
|
fi
|
|
1427
1445
|
|
|
1428
1446
|
# Update date placeholder
|
|
1429
|
-
|
|
1430
|
-
rm -f "${plans_file}.tmp"
|
|
1447
|
+
sed_inplace "s/{{DATE}}/$(date +%Y-%m-%d)/" "$plans_file" 2>/dev/null || true
|
|
1431
1448
|
|
|
1432
1449
|
# Merge existing plans into Active Plans section (after the TOON block closing tag)
|
|
1433
1450
|
if [[ -n "$existing_plans" ]]; then
|
|
@@ -1483,8 +1500,7 @@ cmd_upgrade_planning() {
|
|
|
1483
1500
|
' "$config_file" > "$temp_json" && mv "$temp_json" "$config_file"
|
|
1484
1501
|
else
|
|
1485
1502
|
# Update existing templates_version
|
|
1486
|
-
|
|
1487
|
-
rm -f "${config_file}.tmp"
|
|
1503
|
+
sed_inplace "s/\"templates_version\": \"[^\"]*\"/\"templates_version\": \"$aidevops_version\"/" "$config_file" 2>/dev/null || true
|
|
1488
1504
|
fi
|
|
1489
1505
|
fi
|
|
1490
1506
|
|
|
@@ -2019,9 +2035,9 @@ cmd_help() {
|
|
|
2019
2035
|
echo " aidevops skill remove <name> # Remove an imported skill"
|
|
2020
2036
|
echo ""
|
|
2021
2037
|
echo "Installation:"
|
|
2022
|
-
echo " npm install -g aidevops && aidevops update # via npm"
|
|
2038
|
+
echo " npm install -g aidevops && aidevops update # via npm (recommended)"
|
|
2023
2039
|
echo " brew install marcusquinn/tap/aidevops && aidevops update # via Homebrew"
|
|
2024
|
-
echo "
|
|
2040
|
+
echo " curl -fsSL https://aidevops.sh -o /tmp/aidevops-setup.sh && bash /tmp/aidevops-setup.sh # manual"
|
|
2025
2041
|
echo ""
|
|
2026
2042
|
echo "Documentation: https://github.com/marcusquinn/aidevops"
|
|
2027
2043
|
}
|
package/package.json
CHANGED
package/setup.sh
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
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.105.
|
|
6
|
+
# Version: 2.105.5
|
|
7
7
|
#
|
|
8
|
-
# Quick Install
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# Quick Install:
|
|
9
|
+
# npm install -g aidevops && aidevops update (recommended)
|
|
10
|
+
# brew install marcusquinn/tap/aidevops && aidevops update (Homebrew)
|
|
11
|
+
# curl -fsSL https://aidevops.sh -o /tmp/aidevops-setup.sh && bash /tmp/aidevops-setup.sh (manual)
|
|
11
12
|
|
|
12
13
|
# Colors for output
|
|
13
14
|
GREEN='\033[0;32m'
|
|
@@ -64,6 +65,73 @@ run_with_spinner() {
|
|
|
64
65
|
return $exit_code
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
# Verified install: download script to temp file, inspect, then execute
|
|
69
|
+
# Replaces unsafe curl|sh patterns with download-verify-execute
|
|
70
|
+
# Usage: verified_install "description" "url" [extra_args...]
|
|
71
|
+
# Options (set before calling):
|
|
72
|
+
# VERIFIED_INSTALL_SUDO="true" - run with sudo
|
|
73
|
+
# VERIFIED_INSTALL_SHELL="sh" - use sh instead of bash (default: bash)
|
|
74
|
+
# Returns: 0 on success, 1 on failure
|
|
75
|
+
verified_install() {
|
|
76
|
+
local description="$1"
|
|
77
|
+
local url="$2"
|
|
78
|
+
shift 2
|
|
79
|
+
local extra_args=("$@")
|
|
80
|
+
local shell="${VERIFIED_INSTALL_SHELL:-bash}"
|
|
81
|
+
local use_sudo="${VERIFIED_INSTALL_SUDO:-false}"
|
|
82
|
+
|
|
83
|
+
# Reset options for next call
|
|
84
|
+
VERIFIED_INSTALL_SUDO="false"
|
|
85
|
+
VERIFIED_INSTALL_SHELL="bash"
|
|
86
|
+
|
|
87
|
+
# Create secure temp file
|
|
88
|
+
local tmp_script
|
|
89
|
+
tmp_script=$(mktemp "${TMPDIR:-/tmp}/aidevops-install-XXXXXX.sh") || {
|
|
90
|
+
print_error "Failed to create temp file for $description"
|
|
91
|
+
return 1
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Ensure cleanup on exit from this function
|
|
95
|
+
# shellcheck disable=SC2064
|
|
96
|
+
trap "rm -f '$tmp_script'" RETURN
|
|
97
|
+
|
|
98
|
+
# Download script to file (not piped to shell)
|
|
99
|
+
print_info "Downloading $description install script..."
|
|
100
|
+
if ! curl -fsSL "$url" -o "$tmp_script" 2>/dev/null; then
|
|
101
|
+
print_error "Failed to download $description install script from $url"
|
|
102
|
+
return 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Verify download is non-empty and looks like a script
|
|
106
|
+
if [[ ! -s "$tmp_script" ]]; then
|
|
107
|
+
print_error "Downloaded $description script is empty"
|
|
108
|
+
return 1
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# Basic content safety check: reject binary content
|
|
112
|
+
if file "$tmp_script" 2>/dev/null | grep -qv 'text'; then
|
|
113
|
+
print_error "Downloaded $description script appears to be binary, not a shell script"
|
|
114
|
+
return 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Make executable
|
|
118
|
+
chmod +x "$tmp_script"
|
|
119
|
+
|
|
120
|
+
# Execute from file
|
|
121
|
+
local cmd=("$shell" "$tmp_script" "${extra_args[@]}")
|
|
122
|
+
if [[ "$use_sudo" == "true" ]]; then
|
|
123
|
+
cmd=(sudo "$shell" "$tmp_script" "${extra_args[@]}")
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if "${cmd[@]}"; then
|
|
127
|
+
print_success "$description installed"
|
|
128
|
+
return 0
|
|
129
|
+
else
|
|
130
|
+
print_error "$description installation failed"
|
|
131
|
+
return 1
|
|
132
|
+
fi
|
|
133
|
+
}
|
|
134
|
+
|
|
67
135
|
# Find OpenCode config file (checks multiple possible locations)
|
|
68
136
|
# Returns: path to config file, or empty string if not found
|
|
69
137
|
find_opencode_config() {
|
|
@@ -310,20 +378,36 @@ migrate_agent_to_agents_folder() {
|
|
|
310
378
|
done < <(jq -r '.initialized_repos[].path' "$repos_file" 2>/dev/null)
|
|
311
379
|
fi
|
|
312
380
|
|
|
313
|
-
# 2. Also scan ~/Git/ for any .agent symlinks not in repos.json
|
|
381
|
+
# 2. Also scan ~/Git/ for any .agent symlinks or directories not in repos.json
|
|
314
382
|
if [[ -d "$HOME/Git" ]]; then
|
|
315
|
-
while IFS= read -r -d ''
|
|
383
|
+
while IFS= read -r -d '' agent_path; do
|
|
316
384
|
local repo_dir
|
|
317
|
-
repo_dir=$(dirname "$
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
385
|
+
repo_dir=$(dirname "$agent_path")
|
|
386
|
+
|
|
387
|
+
if [[ -L "$agent_path" ]]; then
|
|
388
|
+
# Symlink: migrate or clean up stale
|
|
389
|
+
if [[ ! -e "$repo_dir/.agents" ]]; then
|
|
390
|
+
local target
|
|
391
|
+
target=$(readlink "$agent_path")
|
|
392
|
+
rm -f "$agent_path"
|
|
393
|
+
ln -s "$target" "$repo_dir/.agents" 2>/dev/null || true
|
|
394
|
+
print_info " Migrated symlink: $agent_path -> .agents"
|
|
395
|
+
((migrated++))
|
|
396
|
+
else
|
|
397
|
+
# .agents already exists, remove stale .agent symlink
|
|
398
|
+
rm -f "$agent_path"
|
|
399
|
+
print_info " Removed stale symlink: $agent_path (.agents already exists)"
|
|
400
|
+
((migrated++))
|
|
401
|
+
fi
|
|
402
|
+
elif [[ -d "$agent_path" ]]; then
|
|
403
|
+
# Directory: rename to .agents if .agents doesn't exist
|
|
404
|
+
if [[ ! -e "$repo_dir/.agents" ]]; then
|
|
405
|
+
mv "$agent_path" "$repo_dir/.agents"
|
|
406
|
+
print_info " Renamed directory: $agent_path -> .agents"
|
|
407
|
+
((migrated++))
|
|
408
|
+
fi
|
|
325
409
|
fi
|
|
326
|
-
done < <(find "$HOME/Git" -maxdepth 3 -name ".agent" -type l -print0 2>/dev/null)
|
|
410
|
+
done < <(find "$HOME/Git" -maxdepth 3 -name ".agent" \( -type l -o -type d \) -print0 2>/dev/null)
|
|
327
411
|
fi
|
|
328
412
|
|
|
329
413
|
# 3. Update AI assistant config files that reference .agent/
|
|
@@ -1211,8 +1295,9 @@ setup_oh_my_zsh() {
|
|
|
1211
1295
|
|
|
1212
1296
|
if [[ "$install_omz" =~ ^[Yy]$ ]]; then
|
|
1213
1297
|
print_info "Installing Oh My Zsh..."
|
|
1214
|
-
# Use --unattended to avoid changing the shell or starting zsh
|
|
1215
|
-
|
|
1298
|
+
# Use verified download + --unattended to avoid changing the shell or starting zsh
|
|
1299
|
+
VERIFIED_INSTALL_SHELL="sh"
|
|
1300
|
+
if verified_install "Oh My Zsh" "https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh" --unattended; then
|
|
1216
1301
|
print_success "Oh My Zsh installed"
|
|
1217
1302
|
|
|
1218
1303
|
# Ensure .zshrc exists (Oh My Zsh creates it, but verify)
|
|
@@ -1235,11 +1320,11 @@ setup_oh_my_zsh() {
|
|
|
1235
1320
|
fi
|
|
1236
1321
|
else
|
|
1237
1322
|
print_warning "Oh My Zsh installation failed"
|
|
1238
|
-
print_info "Install manually:
|
|
1323
|
+
print_info "Install manually: curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -o /tmp/omz-install.sh && sh /tmp/omz-install.sh"
|
|
1239
1324
|
fi
|
|
1240
1325
|
else
|
|
1241
1326
|
print_info "Skipped Oh My Zsh installation"
|
|
1242
|
-
print_info "Install later:
|
|
1327
|
+
print_info "Install later: curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -o /tmp/omz-install.sh && sh /tmp/omz-install.sh"
|
|
1243
1328
|
fi
|
|
1244
1329
|
|
|
1245
1330
|
return 0
|
|
@@ -1720,15 +1805,17 @@ setup_recommended_tools() {
|
|
|
1720
1805
|
pkg_manager=$(detect_package_manager)
|
|
1721
1806
|
case "$pkg_manager" in
|
|
1722
1807
|
apt)
|
|
1723
|
-
# Add packagecloud repo for Tabby
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1808
|
+
# Add packagecloud repo for Tabby (verified download, not piped to sudo)
|
|
1809
|
+
VERIFIED_INSTALL_SUDO="true"
|
|
1810
|
+
if verified_install "Tabby repository (apt)" "https://packagecloud.io/install/repositories/eugeny/tabby/script.deb.sh"; then
|
|
1811
|
+
sudo apt-get install -y tabby-terminal
|
|
1812
|
+
fi
|
|
1727
1813
|
;;
|
|
1728
1814
|
dnf|yum)
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1815
|
+
VERIFIED_INSTALL_SUDO="true"
|
|
1816
|
+
if verified_install "Tabby repository (rpm)" "https://packagecloud.io/install/repositories/eugeny/tabby/script.rpm.sh"; then
|
|
1817
|
+
sudo "$pkg_manager" install -y tabby-terminal
|
|
1818
|
+
fi
|
|
1732
1819
|
;;
|
|
1733
1820
|
pacman)
|
|
1734
1821
|
# AUR package
|
|
@@ -1764,10 +1851,9 @@ setup_recommended_tools() {
|
|
|
1764
1851
|
echo " Download manually: https://zed.dev/download"
|
|
1765
1852
|
fi
|
|
1766
1853
|
elif [[ "$(uname)" == "Linux" ]]; then
|
|
1767
|
-
# Zed provides an install script for Linux (
|
|
1768
|
-
|
|
1769
|
-
if
|
|
1770
|
-
print_success "Zed installed successfully"
|
|
1854
|
+
# Zed provides an install script for Linux (verified download)
|
|
1855
|
+
VERIFIED_INSTALL_SHELL="sh"
|
|
1856
|
+
if verified_install "Zed" "https://zed.dev/install.sh"; then
|
|
1771
1857
|
zed_installed=true
|
|
1772
1858
|
else
|
|
1773
1859
|
print_warning "Failed to install Zed"
|
|
@@ -1955,8 +2041,9 @@ add_local_bin_to_path() {
|
|
|
1955
2041
|
while IFS= read -r rc_file; do
|
|
1956
2042
|
[[ -z "$rc_file" ]] && continue
|
|
1957
2043
|
|
|
1958
|
-
# Create the rc file if it doesn't exist
|
|
2044
|
+
# Create the rc file if it doesn't exist (ensure parent dir exists for fish etc.)
|
|
1959
2045
|
if [[ ! -f "$rc_file" ]]; then
|
|
2046
|
+
mkdir -p "$(dirname "$rc_file")"
|
|
1960
2047
|
touch "$rc_file"
|
|
1961
2048
|
fi
|
|
1962
2049
|
|
|
@@ -2074,7 +2161,7 @@ alias aws-helper './.agents/scripts/aws-helper.sh'
|
|
|
2074
2161
|
ALIASES
|
|
2075
2162
|
)
|
|
2076
2163
|
|
|
2077
|
-
# Check if aliases already exist in any rc file
|
|
2164
|
+
# Check if aliases already exist in any rc file (including fish config)
|
|
2078
2165
|
local any_configured=false
|
|
2079
2166
|
local rc_file
|
|
2080
2167
|
while IFS= read -r rc_file; do
|
|
@@ -2084,6 +2171,13 @@ ALIASES
|
|
|
2084
2171
|
break
|
|
2085
2172
|
fi
|
|
2086
2173
|
done < <(get_all_shell_rcs)
|
|
2174
|
+
# Also check fish config (not included in get_all_shell_rcs on macOS)
|
|
2175
|
+
if [[ "$any_configured" == "false" ]]; then
|
|
2176
|
+
local fish_config="$HOME/.config/fish/config.fish"
|
|
2177
|
+
if grep -q "# AI Assistant Server Access" "$fish_config" 2>/dev/null; then
|
|
2178
|
+
any_configured=true
|
|
2179
|
+
fi
|
|
2180
|
+
fi
|
|
2087
2181
|
|
|
2088
2182
|
if [[ "$any_configured" == "true" ]]; then
|
|
2089
2183
|
print_info "Server Access aliases already configured - Skipping"
|
|
@@ -2604,28 +2698,59 @@ scan_imported_skills() {
|
|
|
2604
2698
|
return 0
|
|
2605
2699
|
fi
|
|
2606
2700
|
|
|
2607
|
-
# Install skill-scanner if not present
|
|
2701
|
+
# Install skill-scanner if not present
|
|
2702
|
+
# Fallback chain: uv -> pipx -> venv+symlink -> pip3 --user (legacy)
|
|
2703
|
+
# PEP 668 (Ubuntu 24.04+) blocks pip3 --user, so we try isolated methods first
|
|
2608
2704
|
if ! command -v skill-scanner &>/dev/null; then
|
|
2609
|
-
|
|
2610
|
-
|
|
2705
|
+
local installed=false
|
|
2706
|
+
|
|
2707
|
+
# 1. uv tool install (preferred - fast, isolated)
|
|
2708
|
+
if [[ "$installed" == "false" ]] && command -v uv &>/dev/null; then
|
|
2709
|
+
print_info "Installing Cisco Skill Scanner via uv..."
|
|
2611
2710
|
if run_with_spinner "Installing cisco-ai-skill-scanner" uv tool install cisco-ai-skill-scanner; then
|
|
2612
|
-
print_success "Cisco Skill Scanner installed"
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2711
|
+
print_success "Cisco Skill Scanner installed via uv"
|
|
2712
|
+
installed=true
|
|
2713
|
+
fi
|
|
2714
|
+
fi
|
|
2715
|
+
|
|
2716
|
+
# 2. pipx install (designed for isolated app installs)
|
|
2717
|
+
if [[ "$installed" == "false" ]] && command -v pipx &>/dev/null; then
|
|
2718
|
+
print_info "Installing Cisco Skill Scanner via pipx..."
|
|
2719
|
+
if run_with_spinner "Installing cisco-ai-skill-scanner" pipx install cisco-ai-skill-scanner; then
|
|
2720
|
+
print_success "Cisco Skill Scanner installed via pipx"
|
|
2721
|
+
installed=true
|
|
2617
2722
|
fi
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2723
|
+
fi
|
|
2724
|
+
|
|
2725
|
+
# 3. venv + symlink (works on PEP 668 systems without uv/pipx)
|
|
2726
|
+
if [[ "$installed" == "false" ]] && command -v python3 &>/dev/null; then
|
|
2727
|
+
local venv_dir="$HOME/.aidevops/.agent-workspace/work/cisco-scanner-env"
|
|
2728
|
+
local bin_dir="$HOME/.local/bin"
|
|
2729
|
+
print_info "Installing Cisco Skill Scanner in isolated venv..."
|
|
2730
|
+
if python3 -m venv "$venv_dir" 2>/dev/null && \
|
|
2731
|
+
"$venv_dir/bin/pip" install cisco-ai-skill-scanner 2>/dev/null; then
|
|
2732
|
+
mkdir -p "$bin_dir"
|
|
2733
|
+
ln -sf "$venv_dir/bin/skill-scanner" "$bin_dir/skill-scanner"
|
|
2734
|
+
print_success "Cisco Skill Scanner installed via venv ($venv_dir)"
|
|
2735
|
+
installed=true
|
|
2622
2736
|
else
|
|
2623
|
-
|
|
2624
|
-
return 0
|
|
2737
|
+
rm -rf "$venv_dir" 2>/dev/null || true
|
|
2625
2738
|
fi
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2739
|
+
fi
|
|
2740
|
+
|
|
2741
|
+
# 4. pip3 --user (legacy fallback, fails on PEP 668 systems)
|
|
2742
|
+
if [[ "$installed" == "false" ]] && command -v pip3 &>/dev/null; then
|
|
2743
|
+
print_info "Installing Cisco Skill Scanner via pip3 --user..."
|
|
2744
|
+
if run_with_spinner "Installing cisco-ai-skill-scanner" pip3 install --user cisco-ai-skill-scanner 2>/dev/null; then
|
|
2745
|
+
print_success "Cisco Skill Scanner installed via pip3"
|
|
2746
|
+
installed=true
|
|
2747
|
+
fi
|
|
2748
|
+
fi
|
|
2749
|
+
|
|
2750
|
+
if [[ "$installed" == "false" ]]; then
|
|
2751
|
+
print_warning "Failed to install Cisco Skill Scanner - skipping security scan"
|
|
2752
|
+
print_info "Install manually with: uv tool install cisco-ai-skill-scanner"
|
|
2753
|
+
print_info "Or: pipx install cisco-ai-skill-scanner"
|
|
2629
2754
|
return 0
|
|
2630
2755
|
fi
|
|
2631
2756
|
fi
|
|
@@ -2904,7 +3029,7 @@ install_mcp_packages() {
|
|
|
2904
3029
|
install_cmd="npm install -g"
|
|
2905
3030
|
else
|
|
2906
3031
|
print_warning "Neither bun nor npm found - cannot install MCP packages"
|
|
2907
|
-
print_info "Install bun (recommended):
|
|
3032
|
+
print_info "Install bun (recommended): npm install -g bun OR brew install oven-sh/bun/bun"
|
|
2908
3033
|
return 0
|
|
2909
3034
|
fi
|
|
2910
3035
|
|
|
@@ -3335,15 +3460,15 @@ setup_beads_ui() {
|
|
|
3335
3460
|
print_warning "Go install failed"
|
|
3336
3461
|
fi
|
|
3337
3462
|
else
|
|
3338
|
-
# Offer
|
|
3463
|
+
# Offer verified install script (download-then-execute, not piped)
|
|
3339
3464
|
read -r -p " Install bv via install script? [Y/n]: " use_script
|
|
3340
3465
|
if [[ "$use_script" =~ ^[Yy]?$ ]]; then
|
|
3341
|
-
if
|
|
3466
|
+
if verified_install "bv (beads viewer)" "https://raw.githubusercontent.com/Dicklesworthstone/beads_viewer/main/install.sh"; then
|
|
3342
3467
|
print_info "Run: bv (in a beads-enabled project)"
|
|
3343
3468
|
((installed_count++))
|
|
3344
3469
|
else
|
|
3345
3470
|
print_warning "Install script failed - try manually:"
|
|
3346
|
-
print_info "
|
|
3471
|
+
print_info " Homebrew: brew tap dicklesworthstone/tap && brew install dicklesworthstone/tap/bv"
|
|
3347
3472
|
fi
|
|
3348
3473
|
else
|
|
3349
3474
|
print_info "Install later:"
|
|
@@ -3417,7 +3542,7 @@ setup_browser_tools() {
|
|
|
3417
3542
|
# Install Bun if not present (required for dev-browser)
|
|
3418
3543
|
if [[ "$has_bun" == "false" ]]; then
|
|
3419
3544
|
print_info "Installing Bun (required for dev-browser)..."
|
|
3420
|
-
if
|
|
3545
|
+
if verified_install "Bun" "https://bun.sh/install"; then
|
|
3421
3546
|
# Source the updated PATH
|
|
3422
3547
|
export BUN_INSTALL="$HOME/.bun"
|
|
3423
3548
|
export PATH="$BUN_INSTALL/bin:$PATH"
|
|
@@ -3670,14 +3795,6 @@ setup_opencode_plugins() {
|
|
|
3670
3795
|
|
|
3671
3796
|
return 0
|
|
3672
3797
|
}
|
|
3673
|
-
|
|
3674
|
-
# Setup Oh-My-OpenCode Plugin (removed - no longer supported)
|
|
3675
|
-
# Kept as stub for backward compatibility with any callers
|
|
3676
|
-
setup_oh_my_opencode() {
|
|
3677
|
-
# Removed - oh-my-opencode no longer supported
|
|
3678
|
-
return 0
|
|
3679
|
-
}
|
|
3680
|
-
|
|
3681
3798
|
setup_seo_mcps() {
|
|
3682
3799
|
print_info "Setting up SEO integrations..."
|
|
3683
3800
|
|