11# Requires -Version 5.1
22<#
33. SYNOPSIS
4- One-shot installer for T3 Code desktop app.
4+ One-shot installer & updater for T3 Code desktop app.
55
66. DESCRIPTION
7- Downloads and installs the latest T3 Code MSI, plus all required
8- dependencies (Node.js, Git, GitHub CLI, provider CLIs) via winget
9- or Chocolatey. Supports future updates through both package managers.
7+ Downloads and installs (or updates) the latest T3 Code MSI, plus all
8+ required dependencies (Node.js, Git, GitHub CLI, provider CLIs) via
9+ winget or Chocolatey.
10+
11+ Run the same command for both install and update — it auto-detects.
1012
1113. EXAMPLE
14+ # Fresh install or update:
1215 iex (irm https://raw.githubusercontent.com/hlsitechio/t3code/main/install.ps1)
1316#>
1417
1518$ErrorActionPreference = " Stop"
16- $ProgressPreference = " SilentlyContinue"
19+ $ProgressPreference = " SilentlyContinue"
1720
18- $repo = " hlsitechio/t3code"
21+ $repo = " hlsitechio/t3code"
1922$appName = " T3 Code"
2023
24+ # ---------------------------------------------------------------------------
25+ # Output helpers
26+ # ---------------------------------------------------------------------------
27+
2128function Write-Step ($msg ) { Write-Host " > $msg " - ForegroundColor Cyan }
2229function Write-Ok ($msg ) { Write-Host " + $msg " - ForegroundColor Green }
2330function Write-Skip ($msg ) { Write-Host " - $msg " - ForegroundColor DarkGray }
2431function Write-Err ($msg ) { Write-Host " x $msg " - ForegroundColor Red }
2532function Write-Warn ($msg ) { Write-Host " ! $msg " - ForegroundColor Yellow }
2633
34+ # ---------------------------------------------------------------------------
35+ # Detect existing T3 Code installation
36+ # ---------------------------------------------------------------------------
37+
38+ function Get-InstalledT3Version {
39+ # Check registry for MSI-installed version
40+ $paths = @ (
41+ " HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" ,
42+ " HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ,
43+ " HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
44+ )
45+ foreach ($path in $paths ) {
46+ try {
47+ $entry = Get-ItemProperty $path - ErrorAction SilentlyContinue |
48+ Where-Object { $_.DisplayName -match " T3.?Code" } |
49+ Select-Object - First 1
50+ if ($entry ) {
51+ return $entry.DisplayVersion
52+ }
53+ } catch {}
54+ }
55+ return $null
56+ }
57+
58+ $installedVersion = Get-InstalledT3Version
59+ $isUpdate = $null -ne $installedVersion
60+
2761Write-Host " "
2862Write-Host " ========================================" - ForegroundColor White
29- Write-Host " T3 Code Installer " - ForegroundColor White
63+ if ($isUpdate ) {
64+ Write-Host " T3 Code Updater (v$installedVersion ) " - ForegroundColor White
65+ } else {
66+ Write-Host " T3 Code Installer " - ForegroundColor White
67+ }
3068Write-Host " ========================================" - ForegroundColor White
3169Write-Host " "
3270
@@ -65,34 +103,37 @@ function Refresh-Path {
65103}
66104
67105# ---------------------------------------------------------------------------
68- # Universal package installer (winget > choco > manual)
106+ # Universal package installer/updater (winget > choco > manual)
69107# ---------------------------------------------------------------------------
70108
71109function Install-Dep {
72110 param (
73111 [string ]$Name ,
74112 [string ]$WingetId ,
75113 [string ]$ChocoId ,
76- [string ]$ManualUrl
114+ [string ]$ManualUrl ,
115+ [switch ]$ForceUpgrade
77116 )
78117
79118 # Try winget first
80119 if ($hasWinget ) {
81- Write-Step " Installing $Name via winget..."
82- $result = winget install -- id $WingetId -- accept- package- agreements -- accept- source- agreements -- disable-interactivity -- silent 2>&1
83- if ($LASTEXITCODE -eq 0 -or " $result " -match " already installed" ) {
84- Write-Ok " $Name installed (winget)"
120+ $action = if ($ForceUpgrade ) { " upgrade" } else { " install" }
121+ Write-Step " $ ( if ($ForceUpgrade ) { ' Updating' } else { ' Installing' } ) $Name via winget..."
122+ $result = winget $action -- id $WingetId -- accept- package- agreements -- accept- source- agreements -- disable-interactivity -- silent 2>&1
123+ if ($LASTEXITCODE -eq 0 -or " $result " -match " already installed" -or " $result " -match " No available upgrade" ) {
124+ Write-Ok " $Name up to date (winget)"
85125 Refresh- Path
86126 return $true
87127 }
88128 }
89129
90130 # Fallback to Chocolatey
91131 if ($hasChoco ) {
92- Write-Step " Installing $Name via Chocolatey..."
93- choco install $ChocoId - y -- no- progress 2> $null
132+ $action = if ($ForceUpgrade ) { " upgrade" } else { " install" }
133+ Write-Step " $ ( if ($ForceUpgrade ) { ' Updating' } else { ' Installing' } ) $Name via Chocolatey..."
134+ choco $action $ChocoId - y -- no- progress 2> $null
94135 if ($LASTEXITCODE -eq 0 ) {
95- Write-Ok " $Name installed (Chocolatey)"
136+ Write-Ok " $Name up to date (Chocolatey)"
96137 Refresh- Path
97138 return $true
98139 }
@@ -114,23 +155,35 @@ Write-Host " -----------------------" -ForegroundColor DarkGray
114155# Node.js
115156if (Test-Command " node" ) {
116157 $nodeVer = & node -- version 2> $null
117- Write-Ok " Node.js $nodeVer (already installed)"
158+ if ($isUpdate ) {
159+ Install-Dep - Name " Node.js LTS" - WingetId " OpenJS.NodeJS.LTS" - ChocoId " nodejs-lts" - ManualUrl " https://nodejs.org" - ForceUpgrade
160+ } else {
161+ Write-Ok " Node.js $nodeVer (already installed)"
162+ }
118163} else {
119164 Install-Dep - Name " Node.js LTS" - WingetId " OpenJS.NodeJS.LTS" - ChocoId " nodejs-lts" - ManualUrl " https://nodejs.org"
120165}
121166
122167# Git
123168if (Test-Command " git" ) {
124169 $gitVer = & git -- version 2> $null
125- Write-Ok " $gitVer (already installed)"
170+ if ($isUpdate ) {
171+ Install-Dep - Name " Git" - WingetId " Git.Git" - ChocoId " git" - ManualUrl " https://git-scm.com" - ForceUpgrade
172+ } else {
173+ Write-Ok " $gitVer (already installed)"
174+ }
126175} else {
127176 Install-Dep - Name " Git" - WingetId " Git.Git" - ChocoId " git" - ManualUrl " https://git-scm.com"
128177}
129178
130179# GitHub CLI
131180if (Test-Command " gh" ) {
132181 $ghVer = & gh -- version 2> $null | Select-Object - First 1
133- Write-Ok " $ghVer (already installed)"
182+ if ($isUpdate ) {
183+ Install-Dep - Name " GitHub CLI" - WingetId " GitHub.cli" - ChocoId " gh" - ManualUrl " https://cli.github.com" - ForceUpgrade
184+ } else {
185+ Write-Ok " $ghVer (already installed)"
186+ }
134187} else {
135188 Install-Dep - Name " GitHub CLI" - WingetId " GitHub.cli" - ChocoId " gh" - ManualUrl " https://cli.github.com"
136189}
@@ -152,7 +205,17 @@ if (Test-Command "npm") {
152205
153206 foreach ($tool in $npmPkgs ) {
154207 if (Test-Command $tool.Cmd ) {
155- Write-Skip " $ ( $tool.Name ) (already installed)"
208+ if ($isUpdate ) {
209+ Write-Step " Updating $ ( $tool.Name ) ..."
210+ npm update - g $tool.Pkg 2> $null
211+ if ($LASTEXITCODE -eq 0 ) {
212+ Write-Ok " $ ( $tool.Name ) updated"
213+ } else {
214+ Write-Warn " $ ( $tool.Name ) update failed (run: npm update -g $ ( $tool.Pkg ) )"
215+ }
216+ } else {
217+ Write-Skip " $ ( $tool.Name ) (already installed)"
218+ }
156219 } else {
157220 Write-Step " Installing $ ( $tool.Name ) ..."
158221 npm install - g $tool.Pkg 2> $null
@@ -169,7 +232,7 @@ if (Test-Command "npm") {
169232}
170233
171234# ---------------------------------------------------------------------------
172- # 3. Download & install T3 Code MSI
235+ # 3. Download & install/update T3 Code MSI
173236# ---------------------------------------------------------------------------
174237
175238Write-Host " "
@@ -179,7 +242,7 @@ Write-Host " -------------------------" -ForegroundColor DarkGray
179242Write-Step " Fetching latest release from GitHub..."
180243
181244try {
182- $headers = @ { " User-Agent" = " T3CodeInstaller/1 .0" }
245+ $headers = @ { " User-Agent" = " T3CodeInstaller/2 .0" }
183246 $release = $null
184247 $msiAsset = $null
185248
@@ -202,63 +265,70 @@ try {
202265 if (-not $msiAsset ) {
203266 Write-Err " No MSI found in releases at github.com/$repo "
204267 Write-Warn " Visit https://github.com/$repo /releases to download manually."
205- exit 1
206- }
207-
208- $msiUrl = $msiAsset.browser_download_url
209- $msiName = $msiAsset.name
210- $sizeMB = [math ]::Round($msiAsset.size / 1 MB , 1 )
211- $tempDir = Join-Path $env: TEMP " t3code-install"
212- $msiPath = Join-Path $tempDir $msiName
268+ # Don't exit — deps were still installed successfully
269+ } else {
270+ $latestVersion = $release.tag_name -replace ' ^v' , ' '
271+ $msiUrl = $msiAsset.browser_download_url
272+ $msiName = $msiAsset.name
273+ $sizeMB = [math ]::Round($msiAsset.size / 1 MB , 1 )
274+
275+ # Compare versions — skip download if already on latest
276+ if ($installedVersion -and $installedVersion -eq $latestVersion ) {
277+ Write-Ok " T3 Code v$installedVersion is already the latest version"
278+ } else {
279+ $tempDir = Join-Path $env: TEMP " t3code-install"
280+ $msiPath = Join-Path $tempDir $msiName
213281
214- if (-not (Test-Path $tempDir )) { New-Item - ItemType Directory - Path $tempDir - Force | Out-Null }
282+ if (-not (Test-Path $tempDir )) { New-Item - ItemType Directory - Path $tempDir - Force | Out-Null }
215283
216- Write-Step " Downloading $msiName ($sizeMB MB)..."
217- Invoke-WebRequest - Uri $msiUrl - OutFile $msiPath - UseBasicParsing
284+ if ($isUpdate ) {
285+ Write-Step " Downloading update: v$installedVersion -> v$latestVersion ($sizeMB MB)..."
286+ } else {
287+ Write-Step " Downloading $msiName ($sizeMB MB)..."
288+ }
289+ Invoke-WebRequest - Uri $msiUrl - OutFile $msiPath - UseBasicParsing
290+
291+ Write-Step " Installing T3 Code (admin prompt may appear)..."
292+ # MSI /i handles both install and upgrade automatically
293+ $proc = Start-Process msiexec.exe - ArgumentList " /i `" $msiPath `" /qb /norestart" - Wait - Verb RunAs - PassThru
294+ if ($proc.ExitCode -eq 0 ) {
295+ if ($isUpdate ) {
296+ Write-Ok " T3 Code updated to v$latestVersion !"
297+ } else {
298+ Write-Ok " T3 Code v$latestVersion installed!"
299+ }
300+ } else {
301+ Write-Err " MSI install returned exit code $ ( $proc.ExitCode ) "
302+ }
218303
219- Write-Step " Installing T3 Code (admin prompt may appear)..."
220- $proc = Start-Process msiexec.exe - ArgumentList " /i `" $msiPath `" /qb /norestart" - Wait - Verb RunAs - PassThru
221- if ($proc.ExitCode -eq 0 ) {
222- Write-Ok " T3 Code $ ( $release.tag_name ) installed!"
223- } else {
224- Write-Err " MSI install returned exit code $ ( $proc.ExitCode ) "
304+ # Cleanup
305+ Remove-Item - Path $tempDir - Recurse - Force - ErrorAction SilentlyContinue
306+ }
225307 }
226-
227- # Cleanup
228- Remove-Item - Path $tempDir - Recurse - Force - ErrorAction SilentlyContinue
229-
230308} catch {
231309 Write-Err " Download/install failed: $_ "
232310 Write-Warn " Visit https://github.com/$repo /releases to download manually."
233- exit 1
234311}
235312
236313# ---------------------------------------------------------------------------
237- # 4. Update channel setup
314+ # 4. Update channel info
238315# ---------------------------------------------------------------------------
239316
240317Write-Host " "
241318Write-Host " [4/4] Update Channels" - ForegroundColor White
242319Write-Host " ---------------------" - ForegroundColor DarkGray
243320
244- # T3 Code has built-in auto -update via electron-updater ( checks GitHub Releases).
245- # Additionally, register with system package managers for CLI updates.
321+ Write-Ok " Auto -update: T3 Code checks GitHub Releases on every launch "
322+ Write-Ok " Manual update: re-run this same command anytime "
246323
247324if ($hasWinget ) {
248- Write-Ok " winget: T3 Code will appear in 'winget upgrade' once published to winget-pkgs"
249- Write-Skip " Future: winget upgrade --id T3Tools.T3Code"
325+ Write-Skip " winget upgrade --all (updates core deps)"
250326}
251-
252327if ($hasChoco ) {
253- Write-Ok " Chocolatey: T3 Code will appear in 'choco upgrade' once published"
254- Write-Skip " Future: choco upgrade t3code -y"
328+ Write-Skip " choco upgrade all -y (updates core deps)"
255329}
256-
257- Write-Ok " Auto-update: T3 Code checks GitHub Releases on every launch"
258-
259- # npm tools can be updated with:
260330if (Test-Command " npm" ) {
261- Write-Skip " Update CLI tools anytime: npm update -g @openai/codex @anthropic-ai/claude-code @google/gemini-cli"
331+ Write-Skip " npm update -g @openai/codex @anthropic-ai/claude-code @google/gemini-cli"
262332}
263333
264334# ---------------------------------------------------------------------------
@@ -267,22 +337,26 @@ if (Test-Command "npm") {
267337
268338Write-Host " "
269339Write-Host " ========================================" - ForegroundColor Green
270- Write-Host " Installation Complete! " - ForegroundColor Green
340+ if ($isUpdate ) {
341+ Write-Host " Update Complete! " - ForegroundColor Green
342+ } else {
343+ Write-Host " Installation Complete! " - ForegroundColor Green
344+ }
271345Write-Host " ========================================" - ForegroundColor Green
272346Write-Host " "
273- Write-Host " Launch T3 Code from the Start Menu or Desktop shortcut." - ForegroundColor White
274- Write-Host " "
275- Write-Host " Quick start:" - ForegroundColor DarkGray
276- Write-Host " 1. Sign in with your AI providers (ChatGPT, Claude, Gemini)" - ForegroundColor DarkGray
277- Write-Host " 2. Connect your GitHub account" - ForegroundColor DarkGray
278- Write-Host " 3. Start coding!" - ForegroundColor DarkGray
279- Write-Host " "
280- Write-Host " Update everything:" - ForegroundColor DarkGray
281- if ($hasWinget ) {
282- Write-Host " winget upgrade --all" - ForegroundColor DarkGray
283- }
284- if ($hasChoco ) {
285- Write-Host " choco upgrade all -y" - ForegroundColor DarkGray
347+
348+ if (-not $isUpdate ) {
349+ Write-Host " Launch T3 Code from the Start Menu or Desktop shortcut." - ForegroundColor White
350+ Write-Host " "
351+ Write-Host " Quick start:" - ForegroundColor DarkGray
352+ Write-Host " 1. Sign in with your AI providers (ChatGPT, Claude, Gemini)" - ForegroundColor DarkGray
353+ Write-Host " 2. Connect your GitHub account" - ForegroundColor DarkGray
354+ Write-Host " 3. Start coding!" - ForegroundColor DarkGray
355+ } else {
356+ Write-Host " Restart T3 Code to use the latest version." - ForegroundColor White
286357}
287- Write-Host " npm update -g @openai/codex @anthropic-ai/claude-code @google/gemini-cli" - ForegroundColor DarkGray
358+
359+ Write-Host " "
360+ Write-Host " Run this command anytime to update:" - ForegroundColor DarkGray
361+ Write-Host " iex (irm https://raw.githubusercontent.com/$repo /main/install.ps1)" - ForegroundColor DarkGray
288362Write-Host " "
0 commit comments