# dovmem installer for Windows - https://dovmem.com # Usage (PowerShell): irm https://dovmem.com/install.ps1 | iex $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' $WheelUrl = 'https://dovmem.com/dl/dovmem-0.3.1-py3-none-any.whl' $WheelSha = '380319659c134a4e8965725bcf7a5576ea629ec60914e66df019f4065a2dbd76' $WheelName = 'dovmem-0.3.1-py3-none-any.whl' $Root = Join-Path $env:USERPROFILE '.devmem' $App = Join-Path $Root 'app' $Bin = Join-Path $Root 'bin' function Say($m) { Write-Host $m } function Fail($m) { Write-Host "x $m" -ForegroundColor Red; throw "dovmem install failed: $m" } function Test-Py($exe, $pre) { try { $out = & $exe @pre -c "import sys; print(1 if sys.version_info >= (3, 9) else 0)" 2>$null return ($LASTEXITCODE -eq 0 -and "$out".Trim() -eq '1') } catch { return $false } } function Find-Python { if ((Get-Command py -ErrorAction SilentlyContinue) -and (Test-Py 'py' @('-3'))) { return ,@('py', @('-3')) } foreach ($n in @('python', 'python3')) { $c = Get-Command $n -ErrorAction SilentlyContinue # Skip the Microsoft Store alias (WindowsApps stub) - it only opens the Store. if ($c -and $c.Source -notlike '*\WindowsApps\*' -and (Test-Py $c.Source @())) { return ,@($c.Source, @()) } } foreach ($v in @('313', '312', '311', '310', '39')) { $p = Join-Path $env:LOCALAPPDATA "Programs\Python\Python$v\python.exe" if ((Test-Path $p) -and (Test-Py $p @())) { return ,@($p, @()) } } return $null } $py = Find-Python if (-not $py) { if (-not (Get-Command winget -ErrorAction SilentlyContinue)) { Fail 'dovmem needs Python 3.9+. Install it from https://www.python.org/downloads/ (tick "Add python.exe to PATH"), then run this again.' } Say '-> Installing Python 3.12 for your user (one time, via winget)...' winget install -e --id Python.Python.3.12 --scope user --silent --accept-package-agreements --accept-source-agreements | Out-Null $env:Path = [Environment]::GetEnvironmentVariable('Path', 'User') + ';' + [Environment]::GetEnvironmentVariable('Path', 'Machine') $py = Find-Python if (-not $py) { Fail 'Python was installed but not found yet. Open a new PowerShell window and run the command again.' } } $PyExe = $py[0]; $PyPre = $py[1] $Tmp = Join-Path ([IO.Path]::GetTempPath()) ('dovmem-' + [guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Path $Tmp | Out-Null try { Say '-> Downloading dovmem...' $Whl = Join-Path $Tmp $WheelName Invoke-WebRequest -UseBasicParsing -Uri $WheelUrl -OutFile $Whl $got = (Get-FileHash -Algorithm SHA256 -Path $Whl).Hash.ToLower() if ($got -ne $WheelSha) { Fail 'Checksum mismatch. The download may be corrupted; please try again.' } Say "-> Installing into $App" & $PyExe @PyPre -m venv $App if ($LASTEXITCODE -ne 0) { Fail 'Could not create a Python environment.' } $VPy = Join-Path $App 'Scripts\python.exe' & $VPy -m pip install --quiet --disable-pip-version-check --no-deps --upgrade $Whl if ($LASTEXITCODE -ne 0) { Fail 'pip could not install dovmem.' } } finally { Remove-Item -Recurse -Force $Tmp -ErrorAction SilentlyContinue } # The devmem / dovmem commands for new terminals New-Item -ItemType Directory -Force -Path $Bin | Out-Null foreach ($n in @('devmem', 'dovmem')) { Set-Content -Path (Join-Path $Bin "$n.cmd") -Encoding ASCII -Value "@`"$App\Scripts\$n.exe`" %*" } $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') if (-not (($userPath -split ';') -contains $Bin)) { [Environment]::SetEnvironmentVariable('Path', (($userPath.TrimEnd(';') + ';' + $Bin).TrimStart(';')), 'User') } $env:Path = $env:Path + ';' + $Bin # Desktop + Start menu icon: opens the dashboard without a console window $PyW = Join-Path $App 'Scripts\pythonw.exe' $Shell = New-Object -ComObject WScript.Shell foreach ($dir in @([Environment]::GetFolderPath('Desktop'), [Environment]::GetFolderPath('Programs'))) { if ($dir -and (Test-Path $dir)) { $lnk = $Shell.CreateShortcut((Join-Path $dir 'dovmem.lnk')) $lnk.TargetPath = $PyW $lnk.Arguments = '-m devmem ui' $lnk.WorkingDirectory = $env:USERPROFILE $lnk.Description = 'dovmem - your AI chats, kept forever' $lnk.Save() } } Say '+ dovmem installed. A "dovmem" icon is on your desktop.' Say '' $lang = if ((Get-UICulture).Name -like 'ar*') { 'ar' } else { 'en' } & (Join-Path $App 'Scripts\devmem.exe') setup --no-shortcut --lang $lang