install-windows.ps1 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #Requires -RunAsAdministrator
  2. <#
  3. .SYNOPSIS
  4. Install modern CLI tools for token-efficient AI coding assistants.
  5. .DESCRIPTION
  6. Installs Rust-based CLI tools that replace verbose legacy commands.
  7. These tools produce cleaner output, saving tokens in AI contexts.
  8. .NOTES
  9. Run as Administrator: Right-click PowerShell > Run as Administrator
  10. #>
  11. $ErrorActionPreference = "Stop"
  12. Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
  13. Write-Host "║ Modern CLI Toolkit Installer (Windows) ║" -ForegroundColor Cyan
  14. Write-Host "║ Token-efficient tools for AI coding assistants ║" -ForegroundColor Cyan
  15. Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
  16. Write-Host ""
  17. # Check winget is available
  18. if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
  19. Write-Host "ERROR: winget not found. Please install App Installer from Microsoft Store." -ForegroundColor Red
  20. exit 1
  21. }
  22. # Tool definitions: [PackageId, DisplayName, Binary]
  23. $tools = @(
  24. # File Search & Navigation
  25. @("sharkdp.fd", "fd (find replacement)", "fd"),
  26. @("BurntSushi.ripgrep.MSVC", "ripgrep (grep replacement)", "rg"),
  27. @("eza-community.eza", "eza (ls replacement)", "eza"),
  28. @("sharkdp.bat", "bat (cat replacement)", "bat"),
  29. @("ajeetdsouza.zoxide", "zoxide (cd replacement)", "zoxide"),
  30. @("Canop.broot", "broot (tree replacement)", "broot"),
  31. # Data Processing
  32. @("chmln.sd", "sd (sed replacement)", "sd"),
  33. @("jqlang.jq", "jq (JSON processor)", "jq"),
  34. @("MikeFarah.yq", "yq (YAML processor)", "yq"),
  35. # Git Operations
  36. @("dandavison.delta", "delta (git diff)", "delta"),
  37. @("Wilfred.difftastic", "difft (semantic diff)", "difft"),
  38. @("JesseDuffield.lazygit", "lazygit (git TUI)", "lazygit"),
  39. @("GitHub.cli", "gh (GitHub CLI)", "gh"),
  40. # System Monitoring
  41. @("bootandy.dust", "dust (du replacement)", "dust"),
  42. @("ClementTsang.bottom", "bottom (top replacement)", "btm"),
  43. @("dalance.procs", "procs (ps replacement)", "procs"),
  44. # Code Analysis
  45. @("XAMPPRocky.Tokei", "tokei (line counter)", "tokei"),
  46. @("ast-grep.ast-grep", "ast-grep (AST search)", "sg"),
  47. @("sharkdp.hyperfine", "hyperfine (benchmarking)", "hyperfine"),
  48. # Interactive Selection
  49. @("junegunn.fzf", "fzf (fuzzy finder)", "fzf"),
  50. # Documentation
  51. @("dbrgn.tealdeer", "tldr (man replacement)", "tldr"),
  52. # Python
  53. @("astral-sh.uv", "uv (pip replacement)", "uv"),
  54. # Task Running
  55. @("Casey.Just", "just (make replacement)", "just")
  56. )
  57. $installed = 0
  58. $skipped = 0
  59. $failed = 0
  60. foreach ($tool in $tools) {
  61. $packageId = $tool[0]
  62. $displayName = $tool[1]
  63. $binary = $tool[2]
  64. Write-Host " Installing $displayName... " -NoNewline
  65. # Check if already installed
  66. if (Get-Command $binary -ErrorAction SilentlyContinue) {
  67. Write-Host "SKIP (already installed)" -ForegroundColor Yellow
  68. $skipped++
  69. continue
  70. }
  71. try {
  72. $result = winget install $packageId --accept-package-agreements --accept-source-agreements --silent 2>&1
  73. if ($LASTEXITCODE -eq 0) {
  74. Write-Host "OK" -ForegroundColor Green
  75. $installed++
  76. } else {
  77. Write-Host "FAILED" -ForegroundColor Red
  78. $failed++
  79. }
  80. } catch {
  81. Write-Host "ERROR: $_" -ForegroundColor Red
  82. $failed++
  83. }
  84. }
  85. Write-Host ""
  86. Write-Host "════════════════════════════════════════════════════════════════" -ForegroundColor Cyan
  87. Write-Host " Results: $installed installed, $skipped skipped, $failed failed" -ForegroundColor Cyan
  88. Write-Host "════════════════════════════════════════════════════════════════" -ForegroundColor Cyan
  89. # Post-install: Update tldr cache
  90. if (Get-Command tldr -ErrorAction SilentlyContinue) {
  91. Write-Host ""
  92. Write-Host "Updating tldr cache..." -NoNewline
  93. tldr --update 2>&1 | Out-Null
  94. Write-Host " OK" -ForegroundColor Green
  95. }
  96. # Post-install: Initialize zoxide
  97. if (Get-Command zoxide -ErrorAction SilentlyContinue) {
  98. Write-Host ""
  99. Write-Host "To enable zoxide, add to your PowerShell profile ($PROFILE):"
  100. Write-Host ' Invoke-Expression (& { (zoxide init powershell | Out-String) })' -ForegroundColor Yellow
  101. }
  102. # Post-install: fzf integration
  103. if (Get-Command fzf -ErrorAction SilentlyContinue) {
  104. Write-Host ""
  105. Write-Host "To enable fzf integration, install PSFzf module:"
  106. Write-Host ' Install-Module PSFzf -Scope CurrentUser' -ForegroundColor Yellow
  107. Write-Host ""
  108. Write-Host "Then add to your PowerShell profile:"
  109. Write-Host ' Import-Module PSFzf' -ForegroundColor Yellow
  110. Write-Host ' Set-PsFzfOption -PSReadlineChordProvider "Ctrl+t" -PSReadlineChordReverseHistory "Ctrl+r"' -ForegroundColor Yellow
  111. }
  112. Write-Host ""
  113. # Install custom CLI wrappers
  114. Write-Host ""
  115. Write-Host "Installing custom CLI wrappers..." -ForegroundColor Cyan
  116. Write-Host "────────────────────────────────"
  117. $localBin = "$env:USERPROFILE\.local\bin"
  118. if (-not (Test-Path $localBin)) {
  119. New-Item -ItemType Directory -Path $localBin -Force | Out-Null
  120. Write-Host " Created $localBin" -ForegroundColor Green
  121. }
  122. # Perplexity CLI wrapper
  123. $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
  124. $perplexitySrc = Join-Path $scriptDir "perplexity.py"
  125. if (Test-Path $perplexitySrc) {
  126. Copy-Item $perplexitySrc "$localBin\perplexity.py" -Force
  127. # Create batch wrapper for Windows
  128. $batchContent = "@echo off`npython `"%USERPROFILE%\.local\bin\perplexity.py`" %*"
  129. Set-Content -Path "$localBin\perplexity.cmd" -Value $batchContent
  130. Write-Host " perplexity CLI: " -NoNewline
  131. Write-Host "OK" -ForegroundColor Green
  132. } else {
  133. Write-Host " perplexity CLI: " -NoNewline
  134. Write-Host "SKIP (perplexity.py not found)" -ForegroundColor Yellow
  135. }
  136. # Check if ~/.local/bin is in PATH
  137. $userPath = [Environment]::GetEnvironmentVariable("Path", "User")
  138. if ($userPath -notlike "*$localBin*") {
  139. Write-Host ""
  140. Write-Host "Add ~/.local/bin to your PATH:" -ForegroundColor Yellow
  141. Write-Host " [Environment]::SetEnvironmentVariable('Path', `$env:Path + ';$localBin', 'User')" -ForegroundColor Yellow
  142. }
  143. Write-Host ""
  144. Write-Host "Verify installation with:" -ForegroundColor Cyan
  145. Write-Host ' which fd rg eza bat zoxide delta difft jq yq sd lazygit gh tokei uv just fzf dust btm procs tldr' -ForegroundColor Yellow
  146. Write-Host ' perplexity --list-models' -ForegroundColor Yellow
  147. Write-Host ""