Problem
The TritonAI Installer takes 15–30 minutes to complete on Windows, while macOS installs in well under a minute. The gap is large enough that users report thinking the installer has hung.
Tracing the full Windows install path (runner.ts → prerequisites.ts → t3code-desktop.ts → codex-vendor.ts), the two dominant time sinks are both consequences of shipping unsigned + downloaded payloads into a Defender-scanned environment.
Root causes (ranked by impact)
1. Unsigned Windows executables (biggest contributor)
The v0.2.8 release notes state: "the outer Setup and portable executables are not Authenticode-signed." This cascades through every step of the install:
- The bundled Harness NSIS installer (
/S silent, t3code-desktop.ts:327) extracts a full unsigned Electron app (hundreds of files) into %LOCALAPPDATA%\Programs. Windows Defender real-time scanning inspects every file as it is written.
- Every
spawn of node.exe, codex.cmd, and powershell.exe re-triggers scanning of unsigned content (runner.ts:436, prerequisites.ts:163).
- SmartScreen reputation checks add their own delay/interaction on the outer Setup.
On a typical campus machine this step alone accounts for an estimated 10–20 minutes. macOS does not hit this because those builds are signed/notarized.
2. Node.js runtime downloaded and extracted at install time
electron-builder.win.json already vendors codex-cli, t3code-desktop, and skills — but not Node.js. On every fresh install, prerequisites.ts:25 downloads node-v22.22.2-win-x64.zip (~30 MB) from nodejs.org and then extracts it via PowerShell Expand-Archive (prerequisites.ts:142), which is single-threaded and slow. Between the network download (campus/VPN), the extraction, and Defender scanning the thousands of extracted files, this is several minutes that could be zero.
Proposed fixes (in priority order)
Fix A — Sign the Windows release artifacts (highest impact)
The repo already has the complete Azure Trusted Signing pipeline wired up:
README documents all 7 required Azure environment variables.
electron-builder.win.json is configured for forceCodeSigning.
scripts/windows-signing.ts and scripts/verify-windows-authenticode.ps1 exist.
npm run release:contract enforces the signing proof.
What is missing is that v0.2.8 shipped without running the signing step. Signing the outer Setup, portable EXE, and the bundled Harness/Node/Codex executables should eliminate the per-file Defender scan penalty and SmartScreen reputation delays. This single change is expected to recover the majority of the install time.
Fix B — Vendor the managed Node.js runtime (high impact)
Add a prepare-node-vendor packaging script (mirroring prepare-codex-cli-vendor.ts) that stages the pinned Node.js win-x64 archive into vendor/node/win-x64/, and add that path to the files array in electron-builder.win.json. Then update ensurePrerequisites (prerequisites.ts) to detect the bundled runtime and skip the download + Expand-Archive path when it is present (falling back to download only for unpackaged/dev runs, as codex already does).
This removes both the network download and the extraction step from the user-facing install. It also makes the install work offline after the installer itself is downloaded.
Secondary optimizations (smaller wins, not the focus of this issue)
Mentioned for completeness; each is seconds to ~1 minute:
- Replace
Expand-Archive with tar -xf (built into Windows 10+) for the fallback download path.
- Coalesce the 5–6 separate
powershell.exe cold-starts (Unblock-File, readWindowsAppVersion, createWindowsDesktopShortcut, NSIS fallback, env-migration finalize) into a single encoded script.
- Deduplicate the three
codex --version launches (runner.ts:206, :248, :236).
Expected outcome
Fix A + Fix B together should bring the Windows install from 15–30 min down to the 2–5 min range, bringing it in line with macOS.
Problem
The TritonAI Installer takes 15–30 minutes to complete on Windows, while macOS installs in well under a minute. The gap is large enough that users report thinking the installer has hung.
Tracing the full Windows install path (
runner.ts→prerequisites.ts→t3code-desktop.ts→codex-vendor.ts), the two dominant time sinks are both consequences of shipping unsigned + downloaded payloads into a Defender-scanned environment.Root causes (ranked by impact)
1. Unsigned Windows executables (biggest contributor)
The v0.2.8 release notes state: "the outer Setup and portable executables are not Authenticode-signed." This cascades through every step of the install:
/Ssilent,t3code-desktop.ts:327) extracts a full unsigned Electron app (hundreds of files) into%LOCALAPPDATA%\Programs. Windows Defender real-time scanning inspects every file as it is written.spawnofnode.exe,codex.cmd, andpowershell.exere-triggers scanning of unsigned content (runner.ts:436,prerequisites.ts:163).On a typical campus machine this step alone accounts for an estimated 10–20 minutes. macOS does not hit this because those builds are signed/notarized.
2. Node.js runtime downloaded and extracted at install time
electron-builder.win.jsonalready vendors codex-cli, t3code-desktop, and skills — but not Node.js. On every fresh install,prerequisites.ts:25downloadsnode-v22.22.2-win-x64.zip(~30 MB) fromnodejs.organd then extracts it via PowerShellExpand-Archive(prerequisites.ts:142), which is single-threaded and slow. Between the network download (campus/VPN), the extraction, and Defender scanning the thousands of extracted files, this is several minutes that could be zero.Proposed fixes (in priority order)
Fix A — Sign the Windows release artifacts (highest impact)
The repo already has the complete Azure Trusted Signing pipeline wired up:
READMEdocuments all 7 required Azure environment variables.electron-builder.win.jsonis configured forforceCodeSigning.scripts/windows-signing.tsandscripts/verify-windows-authenticode.ps1exist.npm run release:contractenforces the signing proof.What is missing is that v0.2.8 shipped without running the signing step. Signing the outer Setup, portable EXE, and the bundled Harness/Node/Codex executables should eliminate the per-file Defender scan penalty and SmartScreen reputation delays. This single change is expected to recover the majority of the install time.
Fix B — Vendor the managed Node.js runtime (high impact)
Add a
prepare-node-vendorpackaging script (mirroringprepare-codex-cli-vendor.ts) that stages the pinned Node.jswin-x64archive intovendor/node/win-x64/, and add that path to thefilesarray inelectron-builder.win.json. Then updateensurePrerequisites(prerequisites.ts) to detect the bundled runtime and skip the download +Expand-Archivepath when it is present (falling back to download only for unpackaged/dev runs, as codex already does).This removes both the network download and the extraction step from the user-facing install. It also makes the install work offline after the installer itself is downloaded.
Secondary optimizations (smaller wins, not the focus of this issue)
Mentioned for completeness; each is seconds to ~1 minute:
Expand-Archivewithtar -xf(built into Windows 10+) for the fallback download path.powershell.execold-starts (Unblock-File,readWindowsAppVersion,createWindowsDesktopShortcut, NSIS fallback, env-migration finalize) into a single encoded script.codex --versionlaunches (runner.ts:206,:248,:236).Expected outcome
Fix A + Fix B together should bring the Windows install from 15–30 min down to the 2–5 min range, bringing it in line with macOS.