Fixes installation scripts.

This commit is contained in:
2025-12-16 00:24:08 +00:00
parent a71c61932e
commit 091af2d21b
7 changed files with 133 additions and 19 deletions
+46
View File
@@ -210,6 +210,51 @@ function Start-Worker {
} }
} }
function Test-OptionalDependencies {
$missingDeps = @()
# Check for Python 3.13+
try {
$pythonVersion = & python --version 2>&1
if ($pythonVersion -match "Python (\d+)\.(\d+)") {
$major = [int]$Matches[1]
$minor = [int]$Matches[2]
if ($major -lt 3 -or ($major -eq 3 -and $minor -lt 13)) {
$missingDeps += "Python 3.13+ (found $major.$minor)"
}
}
} catch {
$missingDeps += "Python 3.13+"
}
# Check for uvx
try {
$null = Get-Command uvx -ErrorAction Stop
} catch {
$missingDeps += "uvx"
}
if ($missingDeps.Count -gt 0) {
Write-Host ""
Write-Warn "Optional dependencies missing (needed for semantic search):"
foreach ($dep in $missingDeps) {
Write-Host " - $dep"
}
Write-Host ""
Write-Info "Install on Windows:"
Write-Host " winget install Python.Python.3.13"
Write-Host " pip install uv"
Write-Host ""
Write-Info "Note: Requires Python 3.13+."
Write-Host ""
Write-Info "Semantic search will be disabled until these are installed."
Write-Info "Core functionality (SQLite storage, full-text search) will work."
Write-Host ""
} else {
Write-Success "Optional dependencies found (semantic search enabled)"
}
}
function Uninstall-ClaudeMnemonic { function Uninstall-ClaudeMnemonic {
param([switch]$KeepData) param([switch]$KeepData)
@@ -286,6 +331,7 @@ Write-Info "Installing version: $Version"
Install-Release -Version $Version Install-Release -Version $Version
Register-Plugin -Version $Version Register-Plugin -Version $Version
Start-Worker Start-Worker
Test-OptionalDependencies
Write-Host "" Write-Host ""
Write-Host "================================================================" -ForegroundColor Green Write-Host "================================================================" -ForegroundColor Green
+36 -12
View File
@@ -133,26 +133,43 @@ download_release() {
tmp_dir=$(mktemp -d) tmp_dir=$(mktemp -d)
trap "rm -rf $tmp_dir" EXIT trap "rm -rf $tmp_dir" EXIT
# Construct download URL # Construct download URL (use .zip for Windows, .tar.gz for others)
local archive_name="claude-mnemonic_${version#v}_${platform}.tar.gz" local archive_ext="tar.gz"
if [[ "$platform" == windows_* ]]; then
archive_ext="zip"
fi
local archive_name="claude-mnemonic_${version#v}_${platform}.${archive_ext}"
local download_url="https://github.com/${GITHUB_REPO}/releases/download/${version}/${archive_name}" local download_url="https://github.com/${GITHUB_REPO}/releases/download/${version}/${archive_name}"
info "Downloading ${archive_name}..." info "Downloading ${archive_name}..."
if ! curl -sSL -o "$tmp_dir/release.tar.gz" "$download_url"; then if ! curl -sSL -o "$tmp_dir/release.${archive_ext}" "$download_url"; then
error "Failed to download release from: $download_url" error "Failed to download release from: $download_url"
fi fi
info "Extracting archive..." info "Extracting archive..."
if ! tar -xzf "$tmp_dir/release.tar.gz" -C "$tmp_dir"; then if [[ "$archive_ext" == "zip" ]]; then
error "Failed to extract archive" if ! unzip -q "$tmp_dir/release.zip" -d "$tmp_dir"; then
error "Failed to extract archive"
fi
else
if ! tar -xzf "$tmp_dir/release.tar.gz" -C "$tmp_dir"; then
error "Failed to extract archive"
fi
fi fi
# Stop existing worker if running # Stop existing worker if running
info "Stopping existing worker (if running)..." info "Stopping existing worker (if running)..."
pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true
pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true
lsof -ti :37777 | xargs kill -9 2>/dev/null || true # Kill process on port 37777 (use lsof on macOS, ss/fuser on Linux)
if command -v lsof &> /dev/null; then
lsof -ti :37777 | xargs kill -9 2>/dev/null || true
elif command -v ss &> /dev/null; then
ss -tlnp 'sport = :37777' 2>/dev/null | awk 'NR>1 {print $6}' | grep -oP 'pid=\K[0-9]+' | xargs -r kill -9 2>/dev/null || true
elif command -v fuser &> /dev/null; then
fuser -k 37777/tcp 2>/dev/null || true
fi
sleep 1 sleep 1
# Create installation directories # Create installation directories
@@ -327,18 +344,18 @@ check_optional_deps() {
case "$(uname -s)" in case "$(uname -s)" in
Darwin) Darwin)
info "Install on macOS:" info "Install on macOS:"
echo " brew install python3" echo " brew install python@3.13"
echo " pip3 install uvx" echo " pip3 install uv"
;; ;;
Linux) Linux)
info "Install on Linux:" info "Install on Linux:"
echo " sudo apt install python3 python3-pip" echo " sudo apt install python3 python3-pip"
echo " pip3 install uvx" echo " pip3 install uv"
;; ;;
MINGW*|MSYS*|CYGWIN*) MINGW*|MSYS*|CYGWIN*)
info "Install on Windows:" info "Install on Windows:"
echo " winget install Python.Python.3" echo " winget install Python.Python.3.13"
echo " pip install uvx" echo " pip install uv"
;; ;;
esac esac
echo "" echo ""
@@ -433,7 +450,14 @@ if [[ "${1:-}" == "--uninstall" ]]; then
info "Stopping worker processes..." info "Stopping worker processes..."
pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true
pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true
lsof -ti :37777 | xargs kill -9 2>/dev/null || true # Kill process on port 37777 (use lsof on macOS, ss/fuser on Linux)
if command -v lsof &> /dev/null; then
lsof -ti :37777 | xargs kill -9 2>/dev/null || true
elif command -v ss &> /dev/null; then
ss -tlnp 'sport = :37777' 2>/dev/null | awk 'NR>1 {print $6}' | grep -oP 'pid=\K[0-9]+' | xargs -r kill -9 2>/dev/null || true
elif command -v fuser &> /dev/null; then
fuser -k 37777/tcp 2>/dev/null || true
fi
sleep 1 sleep 1
info "Removing plugin directories..." info "Removing plugin directories..."
+10 -1
View File
@@ -67,10 +67,19 @@ try {
if (Test-Path $SettingsFile) { if (Test-Path $SettingsFile) {
$Settings = Get-Content $SettingsFile -Raw | ConvertFrom-Json $Settings = Get-Content $SettingsFile -Raw | ConvertFrom-Json
$modified = $false
if ($Settings.enabledPlugins -and $Settings.enabledPlugins.PSObject.Properties[$PluginKey]) { if ($Settings.enabledPlugins -and $Settings.enabledPlugins.PSObject.Properties[$PluginKey]) {
$Settings.enabledPlugins.PSObject.Properties.Remove($PluginKey) $Settings.enabledPlugins.PSObject.Properties.Remove($PluginKey)
$modified = $true
}
# Remove statusline if it's ours
if ($Settings.statusLine -and $Settings.statusLine.command -match "claude-mnemonic") {
$Settings.PSObject.Properties.Remove("statusLine")
$modified = $true
}
if ($modified) {
$Settings | ConvertTo-Json -Depth 10 | Out-File -Encoding UTF8 $SettingsFile $Settings | ConvertTo-Json -Depth 10 | Out-File -Encoding UTF8 $SettingsFile
Write-Success "Removed from settings.json" Write-Success "Removed from settings.json (including statusline)"
} }
} }
+11 -3
View File
@@ -51,7 +51,14 @@ echo ""
info "Stopping worker processes..." info "Stopping worker processes..."
pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true pkill -9 -f 'claude-mnemonic.*worker' 2>/dev/null || true
pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true pkill -9 -f '\.claude/plugins/.*/worker' 2>/dev/null || true
lsof -ti :37777 | xargs kill -9 2>/dev/null || true # Kill process on port 37777 (use lsof on macOS, ss/fuser on Linux)
if command -v lsof &> /dev/null; then
lsof -ti :37777 | xargs kill -9 2>/dev/null || true
elif command -v ss &> /dev/null; then
ss -tlnp 'sport = :37777' 2>/dev/null | awk 'NR>1 {print $6}' | grep -oP 'pid=\K[0-9]+' | xargs -r kill -9 2>/dev/null || true
elif command -v fuser &> /dev/null; then
fuser -k 37777/tcp 2>/dev/null || true
fi
sleep 1 sleep 1
success "Worker processes stopped" success "Worker processes stopped"
@@ -79,8 +86,9 @@ if command -v jq &> /dev/null; then
fi fi
if [[ -f "$SETTINGS_FILE" ]]; then if [[ -f "$SETTINGS_FILE" ]]; then
jq 'del(.enabledPlugins["'"$PLUGIN_KEY"'"])' "$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" && mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE" # Remove plugin from enabled plugins and remove statusline if it's ours
success "Removed from settings.json" jq 'del(.enabledPlugins["'"$PLUGIN_KEY"'"]) | if .statusLine.command | test("claude-mnemonic") then del(.statusLine) else . end' "$SETTINGS_FILE" > "${SETTINGS_FILE}.tmp" && mv "${SETTINGS_FILE}.tmp" "$SETTINGS_FILE"
success "Removed from settings.json (including statusline)"
fi fi
if [[ -f "$MARKETPLACES_FILE" ]]; then if [[ -f "$MARKETPLACES_FILE" ]]; then
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "claude-mnemonic-dashboard", "name": "claude-mnemonic-dashboard",
"version": "v0.6.1-3-gd68a700-dirty", "version": "v0.6.1-4-g0a0dfc1-dirty",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "claude-mnemonic-dashboard", "name": "claude-mnemonic-dashboard",
"version": "v0.6.1-3-gd68a700-dirty", "version": "v0.6.1-4-g0a0dfc1-dirty",
"dependencies": { "dependencies": {
"vue": "^3.5.13" "vue": "^3.5.13"
}, },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "claude-mnemonic-dashboard", "name": "claude-mnemonic-dashboard",
"version": "v0.6.1-3-gd68a700-dirty", "version": "v0.6.1-4-g0a0dfc1-dirty",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+27
View File
@@ -61,11 +61,38 @@ export function useSSE() {
isConnected.value = false isConnected.value = false
} }
// Handle page unload/refresh to ensure SSE connection is closed immediately
const handleBeforeUnload = () => {
disconnect()
}
// Handle pagehide for mobile browsers and bfcache
const handlePageHide = (event: PageTransitionEvent) => {
if (event.persisted) {
// Page is being cached (bfcache), disconnect but don't prevent reconnect
disconnect()
}
}
// Handle pageshow to reconnect if page was restored from bfcache
const handlePageShow = (event: PageTransitionEvent) => {
if (event.persisted && !eventSource) {
connect()
}
}
onMounted(() => { onMounted(() => {
// Add listeners to close SSE on page refresh/navigation
window.addEventListener('beforeunload', handleBeforeUnload)
window.addEventListener('pagehide', handlePageHide)
window.addEventListener('pageshow', handlePageShow)
connect() connect()
}) })
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('beforeunload', handleBeforeUnload)
window.removeEventListener('pagehide', handlePageHide)
window.removeEventListener('pageshow', handlePageShow)
disconnect() disconnect()
}) })